From 1f235dceaa5864e2152ce89fb1072db14023fe25 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 27 Aug 2022 13:24:51 -0400 Subject: [PATCH 01/16] need numpy --- .github/workflows/unittest-macos.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/unittest-macos.yml b/.github/workflows/unittest-macos.yml index 4c7f1316c4..aba0570f2b 100644 --- a/.github/workflows/unittest-macos.yml +++ b/.github/workflows/unittest-macos.yml @@ -41,6 +41,7 @@ jobs: working-directory: build run: | ccache -z + python3 -m pip install numpy python3 -m pip install pyyaml cmake -C ../cmake/presets/clang.cmake \ -C ../cmake/presets/most.cmake \ From 5cd67eaa5c35bb71c1895da54c4793e1f91d6d73 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 27 Aug 2022 13:25:02 -0400 Subject: [PATCH 02/16] avoid file access issues on windows --- unittest/python/python-pizza.py | 1 + 1 file changed, 1 insertion(+) diff --git a/unittest/python/python-pizza.py b/unittest/python/python-pizza.py index cf0aff2e5a..745816d8e1 100644 --- a/unittest/python/python-pizza.py +++ b/unittest/python/python-pizza.py @@ -120,6 +120,7 @@ class PythonDump(unittest.TestCase): self.lmp.command("dump 1 all custom 2 " + dumpfile + " id type mol q x y z vx vy vz") self.lmp.command("dump_modify 1 time yes units yes") self.lmp.command("run 4 post no") + self.lmp.command("undump 1") d = dump.dump(dumpfile) id1, id2 = d.minmax("id") self.assertEqual(id1,1) From b6ce6755d907d2916ff8c1626ffad401f4f0f6ec Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 27 Aug 2022 16:13:00 -0400 Subject: [PATCH 03/16] add Atom::get_style() method --- src/atom.cpp | 15 +++++++++++++++ src/atom.h | 1 + src/info.cpp | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/atom.cpp b/src/atom.cpp index 085b76def5..66552c5508 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -760,6 +760,21 @@ void Atom::setup() if (sortfreq > 0) setup_sort_bins(); } +/* ---------------------------------------------------------------------- */ + +std::string Atom::get_style() +{ + std::string retval = atom_style; + if (retval == "hybrid") { + auto avec_hybrid = dynamic_cast(avec); + for (int i = 0; i < avec_hybrid->nstyles; i++) { + retval += ' '; + retval += avec_hybrid->keywords[i]; + } + } + return retval; +} + /* ---------------------------------------------------------------------- return ptr to AtomVec class if matches style or to matching hybrid sub-class return nullptr if no match diff --git a/src/atom.h b/src/atom.h index 399ad5023c..837711d439 100644 --- a/src/atom.h +++ b/src/atom.h @@ -311,6 +311,7 @@ class Atom : protected Pointers { void init(); void setup(); + std::string get_style(); AtomVec *style_match(const char *); void modify_params(int, char **); void tag_check(); diff --git a/src/info.cpp b/src/info.cpp index dc59bdadee..a93c57780e 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -402,7 +402,7 @@ void Info::command(int narg, char **arg) if (flags & SYSTEM) { fputs("\nSystem information:\n",out); fmt::print(out,"Units = {}\n", update->unit_style); - fmt::print(out,"Atom style = {}\n", atom->atom_style); + fmt::print(out,"Atom style = {}\n", atom->get_style()); fmt::print(out,"Atom map = {}\n", mapstyles[atom->map_style]); if (atom->molecular != Atom::ATOMIC) { const char *msg; From 266cb24bb3b0c97f49967dc06b5dd4c8907f9314 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 27 Aug 2022 16:19:02 -0400 Subject: [PATCH 04/16] improve error messages in set command --- src/set.cpp | 206 +++++++++++++++++++++++++++------------------------- 1 file changed, 108 insertions(+), 98 deletions(-) diff --git a/src/set.cpp b/src/set.cpp index 2843281d78..74ba370b29 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -61,8 +61,8 @@ void Set::command(int narg, char **arg) if (domain->box_exist == 0) error->all(FLERR,"Set command before simulation box is defined"); if (atom->natoms == 0) - error->all(FLERR,"Set command with no atoms existing"); - if (narg < 3) error->all(FLERR,"Illegal set command"); + error->all(FLERR,"Set command on system without atoms"); + if (narg < 4) error->all(FLERR,"Illegal set command: need at least four arguments"); // style and ID info @@ -71,7 +71,7 @@ void Set::command(int narg, char **arg) else if (strcmp(arg[0],"type") == 0) style = TYPE_SELECT; else if (strcmp(arg[0],"group") == 0) style = GROUP_SELECT; else if (strcmp(arg[0],"region") == 0) style = REGION_SELECT; - else error->all(FLERR,"Illegal set command"); + else error->all(FLERR,"Unknown set command style: {}", arg[0]); id = utils::strdup(arg[1]); select = nullptr; @@ -91,125 +91,125 @@ void Set::command(int narg, char **arg) origarg = iarg; if (strcmp(arg[iarg],"type") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set type", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); set(TYPE); iarg += 2; } else if (strcmp(arg[iarg],"type/fraction") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set type/fraction", error); newtype = utils::inumeric(FLERR,arg[iarg+1],false,lmp); fraction = utils::numeric(FLERR,arg[iarg+2],false,lmp); ivalue = utils::inumeric(FLERR,arg[iarg+3],false,lmp); if (newtype <= 0 || newtype > atom->ntypes) - error->all(FLERR,"Invalid value in set command"); + error->all(FLERR,"Invalid type value {} in set type/fraction command", newtype); if (fraction < 0.0 || fraction > 1.0) - error->all(FLERR,"Invalid value in set command"); + error->all(FLERR,"Invalid fraction value {} in set type/fraction command", fraction); if (ivalue <= 0) - error->all(FLERR,"Invalid random number seed in set command"); + error->all(FLERR,"Invalid random number seed {} in set type/fraction command", ivalue); setrandom(TYPE_FRACTION); iarg += 4; } else if (strcmp(arg[iarg],"type/ratio") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set type/ratio", error); newtype = utils::inumeric(FLERR,arg[iarg+1],false,lmp); fraction = utils::numeric(FLERR,arg[iarg+2],false,lmp); ivalue = utils::inumeric(FLERR,arg[iarg+3],false,lmp); if (newtype <= 0 || newtype > atom->ntypes) - error->all(FLERR,"Invalid value in set command"); + error->all(FLERR,"Invalid type value {} in set type/ratio command", newtype); if (fraction < 0.0 || fraction > 1.0) - error->all(FLERR,"Invalid value in set command"); + error->all(FLERR,"Invalid fraction value {} in set type/ratio command", fraction); if (ivalue <= 0) - error->all(FLERR,"Invalid random number seed in set command"); + error->all(FLERR,"Invalid random number seed {} in set type/ratio command", ivalue); setrandom(TYPE_RATIO); iarg += 4; } else if (strcmp(arg[iarg],"type/subset") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set type/subset", error); newtype = utils::inumeric(FLERR,arg[iarg+1],false,lmp); nsubset = utils::bnumeric(FLERR,arg[iarg+2],false,lmp); ivalue = utils::inumeric(FLERR,arg[iarg+3],false,lmp); if (newtype <= 0 || newtype > atom->ntypes) - error->all(FLERR,"Invalid value in set command"); + error->all(FLERR,"Invalid type value {} in set type/subset command", newtype); if (nsubset < 0) - error->all(FLERR,"Invalid value in set command"); + error->all(FLERR,"Invalid subset size {} in set type/subset command", nsubset); if (ivalue <= 0) - error->all(FLERR,"Invalid random number seed in set command"); + error->all(FLERR,"Invalid random number seed {} in set type/subset command", ivalue); setrandom(TYPE_SUBSET); iarg += 4; } else if (strcmp(arg[iarg],"mol") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set mol", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (!atom->molecule_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(MOLECULE); iarg += 2; } else if (strcmp(arg[iarg],"x") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set x", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); set(X); iarg += 2; } else if (strcmp(arg[iarg],"y") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set y", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); set(Y); iarg += 2; } else if (strcmp(arg[iarg],"z") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set z", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); set(Z); iarg += 2; } else if (strcmp(arg[iarg],"vx") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set vx", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); set(VX); iarg += 2; } else if (strcmp(arg[iarg],"vy") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set vy", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); set(VY); iarg += 2; } else if (strcmp(arg[iarg],"vz") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set vz", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); set(VZ); iarg += 2; } else if (strcmp(arg[iarg],"charge") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set charge", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->q_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(CHARGE); iarg += 2; } else if (strcmp(arg[iarg],"mass") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set mass", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->rmass_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(MASS); iarg += 2; } else if (strcmp(arg[iarg],"shape") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set shape", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else xvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (utils::strmatch(arg[iarg+2],"^v_")) varparse(arg[iarg+2],2); @@ -217,30 +217,30 @@ void Set::command(int narg, char **arg) if (utils::strmatch(arg[iarg+3],"^v_")) varparse(arg[iarg+3],3); else zvalue = utils::numeric(FLERR,arg[iarg+3],false,lmp); if (!atom->ellipsoid_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(SHAPE); iarg += 4; } else if (strcmp(arg[iarg],"length") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set length", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->line_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(LENGTH); iarg += 2; } else if (strcmp(arg[iarg],"tri") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set tri", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->tri_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(TRI); iarg += 2; } else if (strcmp(arg[iarg],"dipole") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set dipole", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else xvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (utils::strmatch(arg[iarg+2],"^v_")) varparse(arg[iarg+2],2); @@ -248,16 +248,16 @@ void Set::command(int narg, char **arg) if (utils::strmatch(arg[iarg+3],"^v_")) varparse(arg[iarg+3],3); else zvalue = utils::numeric(FLERR,arg[iarg+3],false,lmp); if (!atom->mu_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(DIPOLE); iarg += 4; } else if (strcmp(arg[iarg],"dipole/random") == 0) { - if (iarg+3 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+3 > narg) utils::missing_cmd_args(FLERR, "set dipole/random", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); dvalue = utils::numeric(FLERR,arg[iarg+2],false,lmp); if (!atom->mu_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); if (dvalue <= 0.0) @@ -294,7 +294,7 @@ void Set::command(int narg, char **arg) iarg += 3; } else if (strcmp(arg[iarg],"quat") == 0) { - if (iarg+5 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+5 > narg) utils::missing_cmd_args(FLERR, "set quat", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else xvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (utils::strmatch(arg[iarg+2],"^v_")) varparse(arg[iarg+2],2); @@ -304,41 +304,41 @@ void Set::command(int narg, char **arg) if (utils::strmatch(arg[iarg+4],"^v_")) varparse(arg[iarg+4],4); else wvalue = utils::numeric(FLERR,arg[iarg+4],false,lmp); if (!atom->ellipsoid_flag && !atom->tri_flag && !atom->body_flag && !atom->quat_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(QUAT); iarg += 5; } else if (strcmp(arg[iarg],"quat/random") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set quat/random", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (!atom->ellipsoid_flag && !atom->tri_flag && !atom->body_flag && !atom->quat_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); setrandom(QUAT_RANDOM); iarg += 2; } else if (strcmp(arg[iarg],"theta") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set theta", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = DEG2RAD * utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->line_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(THETA); iarg += 2; } else if (strcmp(arg[iarg],"theta/random") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set theta/random", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (!atom->line_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0) error->all(FLERR,"Invalid random number seed in set command"); set(THETA_RANDOM); iarg += 2; } else if (strcmp(arg[iarg],"angmom") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set angmom", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else xvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (utils::strmatch(arg[iarg+2],"^v_")) varparse(arg[iarg+2],2); @@ -346,12 +346,12 @@ void Set::command(int narg, char **arg) if (utils::strmatch(arg[iarg+3],"^v_")) varparse(arg[iarg+3],3); else zvalue = utils::numeric(FLERR,arg[iarg+3],false,lmp); if (!atom->angmom_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(ANGMOM); iarg += 4; } else if (strcmp(arg[iarg],"omega") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set omega", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else xvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (utils::strmatch(arg[iarg+2],"^v_")) varparse(arg[iarg+2],2); @@ -359,26 +359,35 @@ void Set::command(int narg, char **arg) if (utils::strmatch(arg[iarg+3],"^v_")) varparse(arg[iarg+3],3); else zvalue = utils::numeric(FLERR,arg[iarg+3],false,lmp); if (!atom->omega_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(OMEGA); iarg += 4; - } else if (strcmp(arg[iarg],"diameter") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + } else if (strcmp(arg[iarg],"radius/atom") == 0) { + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set radius/atom", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->radius_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); + set(RADIUS_ATOM); + iarg += 2; + + } else if (strcmp(arg[iarg],"diameter") == 0) { + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set diameter", error); + if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); + else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); + if (!atom->radius_flag) + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(DIAMETER); iarg += 2; } else if (strcmp(arg[iarg],"density") == 0 || (strcmp(arg[iarg],"density/disc") == 0)) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set density", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->rmass_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (dvalue <= 0.0) error->all(FLERR,"Invalid density in set command"); discflag = 0; if (strcmp(arg[iarg],"density/disc") == 0) { @@ -390,17 +399,17 @@ void Set::command(int narg, char **arg) iarg += 2; } else if (strcmp(arg[iarg],"volume") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set volume", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->vfrac_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (dvalue <= 0.0) error->all(FLERR,"Invalid volume in set command"); set(VOLUME); iarg += 2; } else if (strcmp(arg[iarg],"image") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+4 > narg) utils::missing_cmd_args(FLERR, "set image", error); ximageflag = yimageflag = zimageflag = 0; if (strcmp(arg[iarg+1],"NULL") != 0) { ximageflag = 1; @@ -430,74 +439,74 @@ void Set::command(int narg, char **arg) iarg += 4; } else if (strcmp(arg[iarg],"bond") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set bond", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (atom->avec->bonds_allow == 0) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0 || ivalue > atom->nbondtypes) error->all(FLERR,"Invalid value in set command"); topology(BOND); iarg += 2; } else if (strcmp(arg[iarg],"angle") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set angle", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (atom->avec->angles_allow == 0) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0 || ivalue > atom->nangletypes) error->all(FLERR,"Invalid value in set command"); topology(ANGLE); iarg += 2; } else if (strcmp(arg[iarg],"dihedral") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set dihedral", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (atom->avec->dihedrals_allow == 0) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0 || ivalue > atom->ndihedraltypes) error->all(FLERR,"Invalid value in set command"); topology(DIHEDRAL); iarg += 2; } else if (strcmp(arg[iarg],"improper") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set improper", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); if (atom->avec->impropers_allow == 0) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0 || ivalue > atom->nimpropertypes) error->all(FLERR,"Invalid value in set command"); topology(IMPROPER); iarg += 2; } else if (strcmp(arg[iarg],"sph/e") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set sph/e", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->esph_flag) - error->all(FLERR,"Cannot set meso/e for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(SPH_E); iarg += 2; } else if (strcmp(arg[iarg],"sph/cv") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set sph/cv", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->cv_flag) - error->all(FLERR,"Cannot set meso/cv for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(SPH_CV); iarg += 2; } else if (strcmp(arg[iarg],"sph/rho") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set sph/rho", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->rho_flag) - error->all(FLERR,"Cannot set meso/rho for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(SPH_RHO); iarg += 2; } else if (strcmp(arg[iarg],"edpd/temp") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set edpd/temp", error); if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0; else if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else { @@ -505,12 +514,12 @@ void Set::command(int narg, char **arg) if (dvalue < 0.0) error->all(FLERR,"Illegal set command"); } if (!atom->edpd_flag) - error->all(FLERR,"Cannot set edpd/temp for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(EDPD_TEMP); iarg += 2; } else if (strcmp(arg[iarg],"edpd/cv") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set edpd/cv", error); if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0; else if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else { @@ -518,12 +527,12 @@ void Set::command(int narg, char **arg) if (dvalue < 0.0) error->all(FLERR,"Illegal set command"); } if (!atom->edpd_flag) - error->all(FLERR,"Cannot set edpd/cv for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(EDPD_CV); iarg += 2; } else if (strcmp(arg[iarg],"cc") == 0) { - if (iarg+3 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+3 > narg) utils::missing_cmd_args(FLERR, "set cc", error); if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0; else if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else { @@ -532,31 +541,30 @@ void Set::command(int narg, char **arg) if (cc_index < 1) error->all(FLERR,"Illegal set command"); } if (!atom->tdpd_flag) - error->all(FLERR,"Cannot set cc for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(CC); iarg += 3; } else if (strcmp(arg[iarg],"smd/mass/density") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set smd/mass/density", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->smd_flag) - error->all(FLERR,"Cannot set smd/mass/density for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(SMD_MASS_DENSITY); iarg += 2; } else if (strcmp(arg[iarg],"smd/contact/radius") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set smd/contact/radius", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (!atom->smd_flag) - error->all(FLERR,"Cannot set smd/contact/radius " - "for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(SMD_CONTACT_RADIUS); iarg += 2; } else if (strcmp(arg[iarg],"dpd/theta") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set dpd/theta", error); if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0; else if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else { @@ -564,12 +572,12 @@ void Set::command(int narg, char **arg) if (dvalue < 0.0) error->all(FLERR,"Illegal set command"); } if (!atom->dpd_flag) - error->all(FLERR,"Cannot set dpd/theta for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(DPDTHETA); iarg += 2; } else if (strcmp(arg[iarg],"epsilon") == 0) { - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set epsilon", error); if (strcmp(arg[iarg+1],"NULL") == 0) dvalue = -1.0; else if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else { @@ -577,7 +585,7 @@ void Set::command(int narg, char **arg) if (dvalue < 0.0) error->all(FLERR,"Illegal set command"); } if (!atom->dielectric_flag) - error->all(FLERR,"Cannot set epsilon for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); set(EPSILON); iarg += 2; @@ -588,16 +596,17 @@ void Set::command(int narg, char **arg) int flag,cols; ArgInfo argi(arg[iarg],ArgInfo::DNAME|ArgInfo::INAME); const char *pname = argi.get_name(); - if (iarg+2 > narg) error->all(FLERR,"Illegal set command"); + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set", error); index_custom = atom->find_custom(argi.get_name(),flag,cols); - if (index_custom < 0) error->all(FLERR,"Custom property {} does not exist",pname); + if (index_custom < 0) + error->all(FLERR,"Set keyword or custom property {} does not exist",pname); switch (argi.get_type()) { case ArgInfo::INAME: if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); - if (flag != 0) error->all(FLERR,"Custom property {} is not integer",pname); + if (flag != 0) error->all(FLERR,"Set command custom property {} is not integer",pname); if (argi.get_dim() == 0) { if (cols > 0) @@ -621,14 +630,15 @@ void Set::command(int narg, char **arg) if (argi.get_dim() == 0) { if (cols > 0) - error->all(FLERR,"Set command custom floating-point property is not a vector"); + error->all(FLERR,"Set command custom double property {} is not a vector",pname); set(DVEC); } else if (argi.get_dim() == 1) { if (cols == 0) - error->all(FLERR,"Set command custom floating-point property is not an array"); + error->all(FLERR,"Set command custom double property {} is not an array",pname); icol_custom = argi.get_index1(); if (icol_custom <= 0 || icol_custom > cols) - error->all(FLERR,"Set command per-atom custom integer array is accessed out-of-range"); + error->all(FLERR,"Set command per-atom custom double array {} is " + "accessed out-of-range",pname); set(DARRAY); } else error->all(FLERR,"Illegal set command"); break; @@ -657,8 +667,8 @@ void Set::command(int narg, char **arg) // free local memory - delete [] id; - delete [] select; + delete[] id; + delete[] select; } /* ---------------------------------------------------------------------- @@ -668,7 +678,7 @@ void Set::command(int narg, char **arg) void Set::selection(int n) { - delete [] select; + delete[] select; select = new int[n]; int nlo,nhi; @@ -1457,9 +1467,9 @@ void Set::varparse(const char *name, int m) int ivar = input->variable->find(name+2); if (ivar < 0) - error->all(FLERR,"Variable name for set command does not exist"); + error->all(FLERR,"Variable name {} for set command does not exist", name); if (!input->variable->atomstyle(ivar)) - error->all(FLERR,"Variable for set command is invalid style"); + error->all(FLERR,"Variable {} for set command is invalid style", name); if (m == 1) { varflag1 = 1; ivar1 = ivar; From 42ef22619a0b4bdaa5b6bba1460d201c999c7334 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 27 Aug 2022 16:19:28 -0400 Subject: [PATCH 05/16] add unit test for set and compute property/atom --- unittest/commands/CMakeLists.txt | 4 + unittest/commands/test_set_property.cpp | 193 ++++++++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 unittest/commands/test_set_property.cpp diff --git a/unittest/commands/CMakeLists.txt b/unittest/commands/CMakeLists.txt index deeee00f71..297bd11054 100644 --- a/unittest/commands/CMakeLists.txt +++ b/unittest/commands/CMakeLists.txt @@ -29,6 +29,10 @@ add_executable(test_delete_atoms test_delete_atoms.cpp) target_link_libraries(test_delete_atoms PRIVATE lammps GTest::GMock) add_test(NAME DeleteAtoms COMMAND test_delete_atoms) +add_executable(test_set_property test_set_property.cpp) +target_link_libraries(test_set_property PRIVATE lammps GTest::GMock) +add_test(NAME SetProperty COMMAND test_set_property) + add_executable(test_variables test_variables.cpp) target_link_libraries(test_variables PRIVATE lammps GTest::GMock) add_test(NAME Variables COMMAND test_variables) diff --git a/unittest/commands/test_set_property.cpp b/unittest/commands/test_set_property.cpp new file mode 100644 index 0000000000..7803c99d5f --- /dev/null +++ b/unittest/commands/test_set_property.cpp @@ -0,0 +1,193 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "lammps.h" + +#include "atom.h" +#include "compute.h" +#include "domain.h" +#include "math_const.h" + +#include "../testing/core.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +// whether to print verbose output (i.e. not capturing LAMMPS screen output). +bool verbose = false; + +using LAMMPS_NS::MathConst::MY_PI; +using LAMMPS_NS::utils::split_words; + +namespace LAMMPS_NS { +using ::testing::ContainsRegex; +using ::testing::ExitedWithCode; +using ::testing::StrEq; + +class SetTest : public LAMMPSTest { +protected: + Atom *atom; + Domain *domain; + void SetUp() override + { + testbinary = "SetTest"; + args = {"-log", "none", "-echo", "screen", "-nocite", "-v", "num", "1"}; + LAMMPSTest::SetUp(); + atom = lmp->atom; + domain = lmp->domain; + } + + void TearDown() override { LAMMPSTest::TearDown(); } + + void atomic_system(const std::string &atom_style, const std::string units = "real") + { + BEGIN_HIDE_OUTPUT(); + command("atom_style " + atom_style); + command("atom_modify map array"); + command("units " + units); + command("lattice sc 1.0 origin 0.125 0.125 0.125"); + command("region box block 0 2 0 2 0 2"); + command("create_box 8 box"); + command("create_atoms 1 box"); + command("mass * 1.0"); + command("region left block 0.0 1.0 INF INF INF INF"); + command("region right block 1.0 2.0 INF INF INF INF"); + command("region top block INF INF 0.0 1.0 INF INF"); + command("region bottom block INF INF 1.0 2.0 INF INF"); + command("region front block INF INF INF INF 0.0 1.0"); + command("region back block INF INF INF 1.0 2.0 INF"); + command("group top region top"); + command("group bottom region bottom"); + END_HIDE_OUTPUT(); + } +}; + +TEST_F(SetTest, NoBoxNoAtoms) +{ + ASSERT_EQ(atom->natoms, 0); + ASSERT_EQ(domain->box_exist, 0); + TEST_FAILURE(".*ERROR: Set command before simulation box is.*", command("set type 1 x 0.0");); + + BEGIN_HIDE_OUTPUT(); + command("region box block 0 2 0 2 0 2"); + command("create_box 1 box"); + END_HIDE_OUTPUT(); + TEST_FAILURE(".*ERROR: Set command on system without atoms.*", command("set type 1 x 0.0");); + + BEGIN_HIDE_OUTPUT(); + command("create_atoms 1 single 0.5 0.5 0.5"); + END_HIDE_OUTPUT(); + TEST_FAILURE(".*ERROR: Illegal set command: need at least four.*", command("set type 1 x");); + TEST_FAILURE(".*ERROR: Unknown set command style: xxx.*", command("set xxx 1 x 0.0");); + TEST_FAILURE(".*ERROR: Set keyword or custom property yyy does not exist.*", + command("set type 1 yyy 0.0");); +} + +TEST_F(SetTest, StylesTypes) +{ + atomic_system("molecular"); + ASSERT_EQ(atom->natoms, 8); + + BEGIN_HIDE_OUTPUT(); + command("set group all mol 1"); + command("set group top type 2"); + command("set region back type 3"); + command("set region left mol 2"); + END_HIDE_OUTPUT(); + ASSERT_EQ(atom->type[0], 2); + ASSERT_EQ(atom->type[1], 2); + ASSERT_EQ(atom->type[2], 1); + ASSERT_EQ(atom->type[3], 1); + ASSERT_EQ(atom->type[4], 2); + ASSERT_EQ(atom->type[5], 2); + ASSERT_EQ(atom->type[6], 1); + ASSERT_EQ(atom->type[7], 1); + + BEGIN_HIDE_OUTPUT(); + command("set mol 1 type 4"); + command("set atom 4*7 type 5"); + END_HIDE_OUTPUT(); + ASSERT_EQ(atom->type[0], 2); + ASSERT_EQ(atom->type[1], 4); + ASSERT_EQ(atom->type[2], 1); + ASSERT_EQ(atom->type[3], 5); + ASSERT_EQ(atom->type[4], 5); + ASSERT_EQ(atom->type[5], 5); + ASSERT_EQ(atom->type[6], 5); + ASSERT_EQ(atom->type[7], 4); + + BEGIN_HIDE_OUTPUT(); + command("variable rev atom 9-id"); + command("set group all type v_rev"); + END_HIDE_OUTPUT(); + ASSERT_EQ(atom->type[0], 8); + ASSERT_EQ(atom->type[1], 7); + ASSERT_EQ(atom->type[2], 6); + ASSERT_EQ(atom->type[3], 5); + ASSERT_EQ(atom->type[4], 4); + ASSERT_EQ(atom->type[5], 3); + ASSERT_EQ(atom->type[6], 2); + ASSERT_EQ(atom->type[7], 1); + + BEGIN_HIDE_OUTPUT(); + command("set group all type 1"); + command("set group all type/fraction 2 0.5 453246"); + END_HIDE_OUTPUT(); + int sum = 0; + for (int i = 0; i < 8; ++i) + sum += (atom->type[i] == 2) ? 1 : 0; + ASSERT_EQ(sum, 4); + + BEGIN_HIDE_OUTPUT(); + command("set group all type 1"); + command("set group all type/ratio 2 0.5 5784536"); + END_HIDE_OUTPUT(); + sum = 0; + for (int i = 0; i < 8; ++i) + sum += (atom->type[i] == 2) ? 1 : 0; + ASSERT_EQ(sum, 4); + + BEGIN_HIDE_OUTPUT(); + command("set group all type 1"); + command("set group all type/subset 2 4 784536"); + END_HIDE_OUTPUT(); + sum = 0; + for (int i = 0; i < 8; ++i) + sum += (atom->type[i] == 2) ? 1 : 0; + ASSERT_EQ(sum, 4); +} +} // namespace LAMMPS_NS + +int main(int argc, char **argv) +{ + MPI_Init(&argc, &argv); + ::testing::InitGoogleMock(&argc, argv); + + if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) + std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; + + // handle arguments passed via environment variable + if (const char *var = getenv("TEST_ARGS")) { + std::vector env = split_words(var); + for (auto arg : env) { + if (arg == "-v") { + verbose = true; + } + } + } + + if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true; + + int rv = RUN_ALL_TESTS(); + MPI_Finalize(); + return rv; +} From acf17b4851e5532f2f9db76962f5010d998a725d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 28 Aug 2022 04:29:17 -0400 Subject: [PATCH 06/16] correct pair coeff mixing diagnostic for CLASS2 pair styles --- src/CLASS2/pair_lj_class2.cpp | 1 + src/CLASS2/pair_lj_class2_coul_cut.cpp | 1 + src/CLASS2/pair_lj_class2_coul_long.cpp | 1 + src/pair.cpp | 9 +++++++-- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/CLASS2/pair_lj_class2.cpp b/src/CLASS2/pair_lj_class2.cpp index f86ba3b035..d6348bafa7 100644 --- a/src/CLASS2/pair_lj_class2.cpp +++ b/src/CLASS2/pair_lj_class2.cpp @@ -513,6 +513,7 @@ double PairLJClass2::init_one(int i, int j) pow(sigma[j][j], 3.0) / (pow(sigma[i][i], 6.0) + pow(sigma[j][j], 6.0)); sigma[i][j] = pow((0.5 * (pow(sigma[i][i], 6.0) + pow(sigma[j][j], 6.0))), 1.0 / 6.0); cut[i][j] = mix_distance(cut[i][i], cut[j][j]); + did_mix = true; } lj1[i][j] = 18.0 * epsilon[i][j] * pow(sigma[i][j], 9.0); diff --git a/src/CLASS2/pair_lj_class2_coul_cut.cpp b/src/CLASS2/pair_lj_class2_coul_cut.cpp index c78d9a99e3..6b5ffe9e65 100644 --- a/src/CLASS2/pair_lj_class2_coul_cut.cpp +++ b/src/CLASS2/pair_lj_class2_coul_cut.cpp @@ -277,6 +277,7 @@ double PairLJClass2CoulCut::init_one(int i, int j) sigma[i][j] = pow((0.5 * (pow(sigma[i][i], 6.0) + pow(sigma[j][j], 6.0))), 1.0 / 6.0); cut_lj[i][j] = mix_distance(cut_lj[i][i], cut_lj[j][j]); cut_coul[i][j] = mix_distance(cut_coul[i][i], cut_coul[j][j]); + did_mix = true; } double cut = MAX(cut_lj[i][j], cut_coul[i][j]); diff --git a/src/CLASS2/pair_lj_class2_coul_long.cpp b/src/CLASS2/pair_lj_class2_coul_long.cpp index 03b1378920..839586abcf 100644 --- a/src/CLASS2/pair_lj_class2_coul_long.cpp +++ b/src/CLASS2/pair_lj_class2_coul_long.cpp @@ -711,6 +711,7 @@ double PairLJClass2CoulLong::init_one(int i, int j) pow(sigma[j][j], 3.0) / (pow(sigma[i][i], 6.0) + pow(sigma[j][j], 6.0)); sigma[i][j] = pow((0.5 * (pow(sigma[i][i], 6.0) + pow(sigma[j][j], 6.0))), 1.0 / 6.0); cut_lj[i][j] = mix_distance(cut_lj[i][i], cut_lj[j][j]); + did_mix = true; } double cut = MAX(cut_lj[i][j], cut_coul); diff --git a/src/pair.cpp b/src/pair.cpp index 81f231bb31..c5aed7ee65 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -290,8 +290,13 @@ void Pair::init() if (!manybody_flag && (comm->me == 0)) { const int num_mixed_pairs = atom->ntypes * (atom->ntypes - 1) / 2; - utils::logmesg(lmp,"Generated {} of {} mixed pair_coeff terms from {} mixing rule\n", - mixed_count, num_mixed_pairs, mixing_rule_names[mix_flag]); + // CLASS2 always applies sixthpower mixing to epsilon/sigma + if (utils::strmatch(force->pair_style,"^lj/class2")) + utils::logmesg(lmp,"Generated {} of {} mixed pair_coeff terms from {}/{} mixing rule\n", + mixed_count, num_mixed_pairs, "sixthpower", mixing_rule_names[mix_flag]); + else + utils::logmesg(lmp,"Generated {} of {} mixed pair_coeff terms from {} mixing rule\n", + mixed_count, num_mixed_pairs, mixing_rule_names[mix_flag]); } } From 634496b509b68855375d308672e77b84b4462575 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 28 Aug 2022 12:31:00 -0400 Subject: [PATCH 07/16] consistent naming and style --- unittest/commands/test_compute_global.cpp | 2 +- unittest/commands/test_delete_atoms.cpp | 2 +- unittest/commands/test_groups.cpp | 5 ++--- unittest/commands/test_kim_commands.cpp | 5 ++--- unittest/commands/test_lattice_region.cpp | 5 ++--- unittest/commands/test_regions.cpp | 2 +- unittest/commands/test_reset_ids.cpp | 5 ++--- unittest/commands/test_simple_commands.cpp | 5 ++--- unittest/commands/test_variables.cpp | 5 ++--- unittest/cplusplus/test_advanced_utils.cpp | 2 +- unittest/cplusplus/test_error_class.cpp | 2 +- unittest/formats/test_file_operations.cpp | 3 +-- unittest/formats/test_molecule_file.cpp | 5 ++--- unittest/formats/test_potential_file_reader.cpp | 5 ++--- unittest/formats/test_text_file_reader.cpp | 5 ++--- 15 files changed, 24 insertions(+), 34 deletions(-) diff --git a/unittest/commands/test_compute_global.cpp b/unittest/commands/test_compute_global.cpp index e21acdbca0..83acab08d4 100644 --- a/unittest/commands/test_compute_global.cpp +++ b/unittest/commands/test_compute_global.cpp @@ -304,7 +304,7 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) + if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable diff --git a/unittest/commands/test_delete_atoms.cpp b/unittest/commands/test_delete_atoms.cpp index 34498e9fa2..20d546e69e 100644 --- a/unittest/commands/test_delete_atoms.cpp +++ b/unittest/commands/test_delete_atoms.cpp @@ -164,7 +164,7 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) + if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable diff --git a/unittest/commands/test_groups.cpp b/unittest/commands/test_groups.cpp index a5c1a50f41..1918f67cbf 100644 --- a/unittest/commands/test_groups.cpp +++ b/unittest/commands/test_groups.cpp @@ -316,9 +316,8 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) - std::cout << "Warning: using OpenMPI without exceptions. " - "Death tests will be skipped\n"; + if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { diff --git a/unittest/commands/test_kim_commands.cpp b/unittest/commands/test_kim_commands.cpp index 953b4e5a00..2d9c1cd7d4 100644 --- a/unittest/commands/test_kim_commands.cpp +++ b/unittest/commands/test_kim_commands.cpp @@ -683,9 +683,8 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) - std::cout << "Warning: using OpenMPI without exceptions. " - "Death tests will be skipped\n"; + if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { diff --git a/unittest/commands/test_lattice_region.cpp b/unittest/commands/test_lattice_region.cpp index cc22509dcd..a1ac9bd675 100644 --- a/unittest/commands/test_lattice_region.cpp +++ b/unittest/commands/test_lattice_region.cpp @@ -634,9 +634,8 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) - std::cout << "Warning: using OpenMPI without exceptions. " - "Death tests will be skipped\n"; + if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { diff --git a/unittest/commands/test_regions.cpp b/unittest/commands/test_regions.cpp index 36d251e542..4c70385918 100644 --- a/unittest/commands/test_regions.cpp +++ b/unittest/commands/test_regions.cpp @@ -279,7 +279,7 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) + if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable diff --git a/unittest/commands/test_reset_ids.cpp b/unittest/commands/test_reset_ids.cpp index 1506f9a892..3d577ad24d 100644 --- a/unittest/commands/test_reset_ids.cpp +++ b/unittest/commands/test_reset_ids.cpp @@ -685,9 +685,8 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) - std::cout << "Warning: using OpenMPI without exceptions. " - "Death tests will be skipped\n"; + if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { diff --git a/unittest/commands/test_simple_commands.cpp b/unittest/commands/test_simple_commands.cpp index 2563c09848..ccec6321b3 100644 --- a/unittest/commands/test_simple_commands.cpp +++ b/unittest/commands/test_simple_commands.cpp @@ -552,9 +552,8 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) - std::cout << "Warning: using OpenMPI without exceptions. " - "Death tests will be skipped\n"; + if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { diff --git a/unittest/commands/test_variables.cpp b/unittest/commands/test_variables.cpp index fe39daf43b..bf3f0cc5e9 100644 --- a/unittest/commands/test_variables.cpp +++ b/unittest/commands/test_variables.cpp @@ -585,9 +585,8 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) - std::cout << "Warning: using OpenMPI without exceptions. " - "Death tests will be skipped\n"; + if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { diff --git a/unittest/cplusplus/test_advanced_utils.cpp b/unittest/cplusplus/test_advanced_utils.cpp index 46da2d5d4b..63c029c068 100644 --- a/unittest/cplusplus/test_advanced_utils.cpp +++ b/unittest/cplusplus/test_advanced_utils.cpp @@ -226,7 +226,7 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) + if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable diff --git a/unittest/cplusplus/test_error_class.cpp b/unittest/cplusplus/test_error_class.cpp index a94e6a3e41..ba3187cd61 100644 --- a/unittest/cplusplus/test_error_class.cpp +++ b/unittest/cplusplus/test_error_class.cpp @@ -128,7 +128,7 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) + if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable diff --git a/unittest/formats/test_file_operations.cpp b/unittest/formats/test_file_operations.cpp index b5fd6af7d5..6a3fef48b3 100644 --- a/unittest/formats/test_file_operations.cpp +++ b/unittest/formats/test_file_operations.cpp @@ -494,8 +494,7 @@ int main(int argc, char **argv) ::testing::InitGoogleMock(&argc, argv); if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) - std::cout << "Warning: using OpenMPI without exceptions. " - "Death tests will be skipped\n"; + std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { diff --git a/unittest/formats/test_molecule_file.cpp b/unittest/formats/test_molecule_file.cpp index d84aa1c960..77a80c8c5f 100644 --- a/unittest/formats/test_molecule_file.cpp +++ b/unittest/formats/test_molecule_file.cpp @@ -303,9 +303,8 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) - std::cout << "Warning: using OpenMPI without exceptions. " - "Death tests will be skipped\n"; + if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { diff --git a/unittest/formats/test_potential_file_reader.cpp b/unittest/formats/test_potential_file_reader.cpp index db235722a4..e9b633690e 100644 --- a/unittest/formats/test_potential_file_reader.cpp +++ b/unittest/formats/test_potential_file_reader.cpp @@ -325,9 +325,8 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) - std::cout << "Warning: using OpenMPI without exceptions. " - "Death tests will be skipped\n"; + if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { diff --git a/unittest/formats/test_text_file_reader.cpp b/unittest/formats/test_text_file_reader.cpp index 325166a2b4..ba1218b069 100644 --- a/unittest/formats/test_text_file_reader.cpp +++ b/unittest/formats/test_text_file_reader.cpp @@ -166,9 +166,8 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) - std::cout << "Warning: using OpenMPI without exceptions. " - "Death tests will be skipped\n"; + if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { From bb6ea422b707baddc397fe7a3a91038b1b550cd0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 28 Aug 2022 17:22:26 -0400 Subject: [PATCH 08/16] avoid global namespace import in header, more consistency --- unittest/commands/test_compute_global.cpp | 7 ++----- unittest/commands/test_delete_atoms.cpp | 7 ++----- unittest/commands/test_groups.cpp | 4 ++-- unittest/commands/test_kim_commands.cpp | 4 ++-- unittest/commands/test_lattice_region.cpp | 6 ++---- unittest/commands/test_regions.cpp | 6 ++---- unittest/commands/test_reset_ids.cpp | 7 ++----- unittest/commands/test_set_property.cpp | 9 +++------ unittest/commands/test_simple_commands.cpp | 6 ++---- unittest/commands/test_variables.cpp | 8 +++----- unittest/cplusplus/test_advanced_utils.cpp | 6 ++---- unittest/cplusplus/test_error_class.cpp | 7 ++----- unittest/formats/compressed_dump_test_main.cpp | 2 +- unittest/formats/test_dump_atom.cpp | 5 ++++- unittest/formats/test_dump_cfg.cpp | 4 +++- unittest/formats/test_dump_custom.cpp | 5 +++-- unittest/formats/test_dump_local.cpp | 4 +++- unittest/formats/test_dump_netcdf.cpp | 4 +++- unittest/testing/core.h | 12 +++++++----- 19 files changed, 50 insertions(+), 63 deletions(-) diff --git a/unittest/commands/test_compute_global.cpp b/unittest/commands/test_compute_global.cpp index 83acab08d4..95164d4a09 100644 --- a/unittest/commands/test_compute_global.cpp +++ b/unittest/commands/test_compute_global.cpp @@ -26,8 +26,6 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::utils::split_words; - namespace LAMMPS_NS { #define STRINGIFY(val) XSTR(val) @@ -296,7 +294,6 @@ TEST_F(ComputeGlobalTest, Reduction) EXPECT_DOUBLE_EQ(rep[2], 26); EXPECT_DOUBLE_EQ(rep[3], max[0]); } - } // namespace LAMMPS_NS int main(int argc, char **argv) @@ -304,12 +301,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_delete_atoms.cpp b/unittest/commands/test_delete_atoms.cpp index 20d546e69e..2a7cab4718 100644 --- a/unittest/commands/test_delete_atoms.cpp +++ b/unittest/commands/test_delete_atoms.cpp @@ -31,9 +31,6 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::MathConst::MY_PI; -using LAMMPS_NS::utils::split_words; - namespace LAMMPS_NS { using ::testing::ContainsRegex; using ::testing::ExitedWithCode; @@ -164,12 +161,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_groups.cpp b/unittest/commands/test_groups.cpp index 1918f67cbf..8247675b82 100644 --- a/unittest/commands/test_groups.cpp +++ b/unittest/commands/test_groups.cpp @@ -316,12 +316,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_kim_commands.cpp b/unittest/commands/test_kim_commands.cpp index 2d9c1cd7d4..1bb070ad6c 100644 --- a/unittest/commands/test_kim_commands.cpp +++ b/unittest/commands/test_kim_commands.cpp @@ -683,12 +683,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_lattice_region.cpp b/unittest/commands/test_lattice_region.cpp index a1ac9bd675..257fe6a596 100644 --- a/unittest/commands/test_lattice_region.cpp +++ b/unittest/commands/test_lattice_region.cpp @@ -32,8 +32,6 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::utils::split_words; - namespace LAMMPS_NS { using ::testing::ContainsRegex; using ::testing::ExitedWithCode; @@ -634,12 +632,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_regions.cpp b/unittest/commands/test_regions.cpp index 4c70385918..2ced0c45f5 100644 --- a/unittest/commands/test_regions.cpp +++ b/unittest/commands/test_regions.cpp @@ -30,8 +30,6 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::utils::split_words; - namespace LAMMPS_NS { using ::testing::ExitedWithCode; using ::testing::StrEq; @@ -279,12 +277,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_reset_ids.cpp b/unittest/commands/test_reset_ids.cpp index 3d577ad24d..cd311616aa 100644 --- a/unittest/commands/test_reset_ids.cpp +++ b/unittest/commands/test_reset_ids.cpp @@ -29,8 +29,6 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::utils::split_words; - namespace LAMMPS_NS { #define GETIDX(i) lmp->atom->map(i) @@ -677,7 +675,6 @@ TEST_F(ResetMolIDsTest, FailOnlyMolecular) END_HIDE_OUTPUT(); TEST_FAILURE(".*ERROR: Can only use reset_mol_ids.*", command("reset_mol_ids all");); } - } // namespace LAMMPS_NS int main(int argc, char **argv) @@ -685,12 +682,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_set_property.cpp b/unittest/commands/test_set_property.cpp index 7803c99d5f..0bd58cb53b 100644 --- a/unittest/commands/test_set_property.cpp +++ b/unittest/commands/test_set_property.cpp @@ -25,14 +25,11 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::MathConst::MY_PI; -using LAMMPS_NS::utils::split_words; - -namespace LAMMPS_NS { using ::testing::ContainsRegex; using ::testing::ExitedWithCode; using ::testing::StrEq; +namespace LAMMPS_NS { class SetTest : public LAMMPSTest { protected: Atom *atom; @@ -172,12 +169,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_simple_commands.cpp b/unittest/commands/test_simple_commands.cpp index ccec6321b3..5889f09eb0 100644 --- a/unittest/commands/test_simple_commands.cpp +++ b/unittest/commands/test_simple_commands.cpp @@ -36,8 +36,6 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::utils::split_words; - namespace LAMMPS_NS { using ::testing::ContainsRegex; using ::testing::ExitedWithCode; @@ -552,12 +550,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/commands/test_variables.cpp b/unittest/commands/test_variables.cpp index bf3f0cc5e9..848331abe2 100644 --- a/unittest/commands/test_variables.cpp +++ b/unittest/commands/test_variables.cpp @@ -32,13 +32,11 @@ // whether to print verbose output (i.e. not capturing LAMMPS screen output). bool verbose = false; -using LAMMPS_NS::MathConst::MY_PI; -using LAMMPS_NS::utils::split_words; - namespace LAMMPS_NS { using ::testing::ContainsRegex; using ::testing::ExitedWithCode; using ::testing::StrEq; +using MathConst::MY_PI; class VariableTest : public LAMMPSTest { protected: @@ -585,12 +583,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/cplusplus/test_advanced_utils.cpp b/unittest/cplusplus/test_advanced_utils.cpp index 63c029c068..6b71c9ea34 100644 --- a/unittest/cplusplus/test_advanced_utils.cpp +++ b/unittest/cplusplus/test_advanced_utils.cpp @@ -16,7 +16,6 @@ bool verbose = false; namespace LAMMPS_NS { - class Advanced_utils : public LAMMPSTest { protected: Error *error; @@ -218,7 +217,6 @@ TEST_F(Advanced_utils, expand_args) delete[] args[i]; delete[] args; } - } // namespace LAMMPS_NS int main(int argc, char **argv) @@ -226,12 +224,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = utils::split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/cplusplus/test_error_class.cpp b/unittest/cplusplus/test_error_class.cpp index ba3187cd61..779cbfbba6 100644 --- a/unittest/cplusplus/test_error_class.cpp +++ b/unittest/cplusplus/test_error_class.cpp @@ -16,9 +16,7 @@ bool verbose = false; namespace LAMMPS_NS { - using ::testing::ContainsRegex; -using utils::split_words; class Error_class : public LAMMPSTest { protected: @@ -120,7 +118,6 @@ TEST_F(Error_class, all) { TEST_FAILURE("ERROR: one error.*test_error_class.cpp:.*", error->all(FLERR, "one error");); }; - } // namespace LAMMPS_NS int main(int argc, char **argv) @@ -128,12 +125,12 @@ int main(int argc, char **argv) MPI_Init(&argc, &argv); ::testing::InitGoogleMock(&argc, argv); - if (platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) + if (LAMMPS_NS::platform::mpi_vendor() == "Open MPI" && !Info::has_exceptions()) std::cout << "Warning: using OpenMPI without exceptions. Death tests will be skipped\n"; // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/formats/compressed_dump_test_main.cpp b/unittest/formats/compressed_dump_test_main.cpp index c96682d8b7..5f775a8843 100644 --- a/unittest/formats/compressed_dump_test_main.cpp +++ b/unittest/formats/compressed_dump_test_main.cpp @@ -50,7 +50,7 @@ int main(int argc, char **argv) // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = utils::split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/formats/test_dump_atom.cpp b/unittest/formats/test_dump_atom.cpp index 762a01e648..12dd8bee8a 100644 --- a/unittest/formats/test_dump_atom.cpp +++ b/unittest/formats/test_dump_atom.cpp @@ -28,6 +28,8 @@ using ::testing::Eq; char *BINARY2TXT_EXECUTABLE = nullptr; bool verbose = false; +namespace LAMMPS_NS { + class DumpAtomTest : public MeltTest { std::string dump_style = "atom"; @@ -678,6 +680,7 @@ TEST_F(DumpAtomTest, binary_write_dump) delete_file(reference); delete_file(dump_file); } +} int main(int argc, char **argv) { @@ -686,7 +689,7 @@ int main(int argc, char **argv) // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = utils::split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/formats/test_dump_cfg.cpp b/unittest/formats/test_dump_cfg.cpp index e51da8331a..acd839282d 100644 --- a/unittest/formats/test_dump_cfg.cpp +++ b/unittest/formats/test_dump_cfg.cpp @@ -23,6 +23,7 @@ using ::testing::Eq; bool verbose = false; +namespace LAMMPS_NS { class DumpCfgTest : public MeltTest { std::string dump_style = "cfg"; @@ -143,6 +144,7 @@ TEST_F(DumpCfgTest, no_unwrap_no_buffer_run0) ASSERT_THAT(lines[0], Eq("Number of particles = 32")); delete_file("dump_cfg_no_unwrap_no_buffer_run0.melt.cfg"); } +} int main(int argc, char **argv) { @@ -151,7 +153,7 @@ int main(int argc, char **argv) // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = utils::split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/formats/test_dump_custom.cpp b/unittest/formats/test_dump_custom.cpp index 72b4adcc87..d1bae9d28f 100644 --- a/unittest/formats/test_dump_custom.cpp +++ b/unittest/formats/test_dump_custom.cpp @@ -26,6 +26,7 @@ using ::testing::Eq; char *BINARY2TXT_EXECUTABLE = nullptr; bool verbose = false; +namespace LAMMPS_NS { class DumpCustomTest : public MeltTest { std::string dump_style = "custom"; @@ -383,7 +384,7 @@ TEST_F(DumpCustomTest, rerun_bin) ASSERT_NEAR(pe_2, pe_rerun, 1.0e-14); delete_file(dump_file); } - +} int main(int argc, char **argv) { MPI_Init(&argc, &argv); @@ -391,7 +392,7 @@ int main(int argc, char **argv) // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = utils::split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/formats/test_dump_local.cpp b/unittest/formats/test_dump_local.cpp index ead071743c..5735f4dc7c 100644 --- a/unittest/formats/test_dump_local.cpp +++ b/unittest/formats/test_dump_local.cpp @@ -28,6 +28,7 @@ using ::testing::Eq; char *BINARY2TXT_EXECUTABLE = nullptr; bool verbose = false; +namespace LAMMPS_NS { class DumpLocalTest : public MeltTest { std::string dump_style = "local"; @@ -237,6 +238,7 @@ TEST_F(DumpLocalTest, triclinic_run0) ASSERT_EQ(utils::split_words(lines[7]).size(), 3); delete_file(dump_file); } +} int main(int argc, char **argv) { @@ -245,7 +247,7 @@ int main(int argc, char **argv) // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = utils::split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/formats/test_dump_netcdf.cpp b/unittest/formats/test_dump_netcdf.cpp index 6d377369ee..0b016d0efb 100644 --- a/unittest/formats/test_dump_netcdf.cpp +++ b/unittest/formats/test_dump_netcdf.cpp @@ -31,6 +31,7 @@ using ::testing::Eq; char *NCDUMP_EXECUTABLE = nullptr; bool verbose = false; +namespace LAMMPS_NS { class DumpNetCDFTest : public MeltTest { std::string dump_style = "netcdf"; @@ -386,6 +387,7 @@ TEST_F(DumpNetCDFTest, run0_mpi) } delete_file(dump_file); } +} int main(int argc, char **argv) { @@ -394,7 +396,7 @@ int main(int argc, char **argv) // handle arguments passed via environment variable if (const char *var = getenv("TEST_ARGS")) { - std::vector env = utils::split_words(var); + std::vector env = LAMMPS_NS::utils::split_words(var); for (auto arg : env) { if (arg == "-v") { verbose = true; diff --git a/unittest/testing/core.h b/unittest/testing/core.h index 81a7112934..5b2aba6fd3 100644 --- a/unittest/testing/core.h +++ b/unittest/testing/core.h @@ -26,7 +26,9 @@ #include #include -using namespace LAMMPS_NS; +using LAMMPS_NS::Info; +using LAMMPS_NS::LAMMPS; +using LAMMPS_NS::LAMMPSException; using ::testing::ContainsRegex; @@ -37,7 +39,7 @@ using ::testing::ContainsRegex; auto mesg = ::testing::internal::GetCapturedStdout(); \ ASSERT_THAT(mesg, ContainsRegex(errmsg)); \ } else { \ - if (platform::mpi_vendor() != "Open MPI") { \ + if (LAMMPS_NS::platform::mpi_vendor() != "Open MPI") { \ ::testing::internal::CaptureStdout(); \ ASSERT_DEATH({__VA_ARGS__}, ""); \ auto mesg = ::testing::internal::GetCapturedStdout(); \ @@ -101,7 +103,7 @@ public: double get_variable_value(const std::string &name) { - char *str = utils::strdup(fmt::format("v_{}", name)); + char *str = LAMMPS_NS::utils::strdup(fmt::format("v_{}", name)); double value = lmp->input->variable->compute_equal(str); delete[] str; return value; @@ -122,9 +124,9 @@ protected: { int argc = args.size() + 1; char **argv = new char *[argc]; - argv[0] = utils::strdup(testbinary); + argv[0] = LAMMPS_NS::utils::strdup(testbinary); for (int i = 1; i < argc; i++) { - argv[i] = utils::strdup(args[i - 1]); + argv[i] = LAMMPS_NS::utils::strdup(args[i - 1]); } HIDE_OUTPUT([&] { From 74bbbb9e17b3878bb920443a0578512e1017ede2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 28 Aug 2022 18:57:19 -0400 Subject: [PATCH 09/16] rename "set spin" to "set spin/atom" and "set spin/random" to "set spin/atom/random" this also adds unit tests and improves error checking and messages --- doc/src/set.rst | 18 ++-- src/set.cpp | 56 ++++++++--- unittest/commands/test_set_property.cpp | 125 ++++++++++++++++++++++++ 3 files changed, 178 insertions(+), 21 deletions(-) diff --git a/doc/src/set.rst b/doc/src/set.rst index 5bc2cfb957..c6c44ceb45 100644 --- a/doc/src/set.rst +++ b/doc/src/set.rst @@ -15,7 +15,7 @@ Syntax * one or more keyword/value pairs may be appended * keyword = *type* or *type/fraction* or *type/ratio* or *type/subset* or *mol* or *x* or *y* or *z* or *vx* or *vy* or *vz* or *charge* or - *dipole* or *dipole/random* or *quat* or *spin* or *spin/random* or + *dipole* or *dipole/random* or *quat* or *spin/atom* or *spin/atom/random* or *quat* or *quat/random* or *diameter* or *shape* or *length* or *tri* or *theta* or *theta/random* or *angmom* or *omega* or *mass* or *density* or *density/disc* or @@ -55,11 +55,11 @@ Syntax *dipole/random* value = seed Dlen seed = random # seed (positive integer) for dipole moment orientations Dlen = magnitude of dipole moment (dipole units) - *spin* values = g x y z + *spin/atom* values = g x y z g = magnitude of magnetic spin vector (in Bohr magneton's unit) x,y,z = orientation of magnetic spin vector any of x,y,z can be an atom-style variable (see below) - *spin/random* value = seed Dlen + *spin/atom/random* value = seed Dlen seed = random # seed (positive integer) for magnetic spin orientations Dlen = magnitude of magnetic spin vector (in Bohr magneton's unit) *quat* values = a b c theta @@ -277,14 +277,18 @@ the orientation of a particular atom is the same, regardless of how many processors are being used. This keyword does not allow use of an atom-style variable. -Keyword *spin* uses the specified g value to set the magnitude of the +.. versionchanged:: TBD + +Keyword *spin/atom* uses the specified g value to set the magnitude of the magnetic spin vectors, and the x,y,z values as components of a vector to set as the orientation of the magnetic spin vectors of the selected -atoms. +atoms. This keyword was previously called *spin*. -Keyword *spin/random* randomizes the orientation of the magnetic spin +.. versionchanged:: TBD + +Keyword *spin/atom/random* randomizes the orientation of the magnetic spin vectors for the selected atoms and sets the magnitude of each to the -specified *Dlen* value. +specified *Dlen* value. This keyword was previously called *spin/random*. Keyword *quat* uses the specified values to create a quaternion (4-vector) that represents the orientation of the selected atoms. The diff --git a/src/set.cpp b/src/set.cpp index 74ba370b29..601bdd9e56 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -46,9 +46,9 @@ enum{ATOM_SELECT,MOL_SELECT,TYPE_SELECT,GROUP_SELECT,REGION_SELECT}; enum{TYPE,TYPE_FRACTION,TYPE_RATIO,TYPE_SUBSET, MOLECULE,X,Y,Z,VX,VY,VZ,CHARGE,MASS,SHAPE,LENGTH,TRI, - DIPOLE,DIPOLE_RANDOM,SPIN,SPIN_RANDOM,QUAT,QUAT_RANDOM, - THETA,THETA_RANDOM,ANGMOM,OMEGA, - DIAMETER,DENSITY,VOLUME,IMAGE,BOND,ANGLE,DIHEDRAL,IMPROPER, + DIPOLE,DIPOLE_RANDOM,SPIN_ATOM,SPIN_RANDOM,SPIN_ELECTRON,RADIUS_ELECTRON, + QUAT,QUAT_RANDOM,THETA,THETA_RANDOM,ANGMOM,OMEGA, + DIAMETER,RADIUS_ATOM,DENSITY,VOLUME,IMAGE,BOND,ANGLE,DIHEDRAL,IMPROPER, SPH_E,SPH_CV,SPH_RHO,EDPD_TEMP,EDPD_CV,CC,SMD_MASS_DENSITY, SMD_CONTACT_RADIUS,DPDTHETA,EPSILON,IVEC,DVEC,IARRAY,DARRAY}; @@ -265,8 +265,10 @@ void Set::command(int narg, char **arg) setrandom(DIPOLE_RANDOM); iarg += 3; - } else if (strcmp(arg[iarg],"spin") == 0) { - if (iarg+4 > narg) error->all(FLERR,"Illegal set command"); + } else if ((strcmp(arg[iarg],"spin") == 0) || (strcmp(arg[iarg],"spin/atom") == 0)) { + if ((strcmp(arg[iarg],"spin") == 0) && (comm->me == 0)) + error->warning(FLERR, "Set attribute spin is deprecated. Please use spin/atom instead."); + if (iarg+5 > narg) utils::missing_cmd_args(FLERR, "set spin/atom", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); if (utils::strmatch(arg[iarg+2],"^v_")) varparse(arg[iarg+2],2); @@ -275,24 +277,50 @@ void Set::command(int narg, char **arg) else yvalue = utils::numeric(FLERR,arg[iarg+3],false,lmp); if (utils::strmatch(arg[iarg+4],"^v_")) varparse(arg[iarg+4],4); else zvalue = utils::numeric(FLERR,arg[iarg+4],false,lmp); + if ((xvalue == 0.0) && (yvalue == 0.0) && (zvalue == 0.0)) + error->all(FLERR,"At least one spin vector component must be non-zero"); if (!atom->sp_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); - set(SPIN); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); + if (dvalue <= 0.0) + error->all(FLERR,"Invalid spin magnitude {} in set {} command", dvalue, arg[iarg]); + set(SPIN_ATOM); iarg += 5; - } else if (strcmp(arg[iarg],"spin/random") == 0) { - if (iarg+3 > narg) error->all(FLERR,"Illegal set command"); + } else if ((strcmp(arg[iarg],"spin/random") == 0) || + (strcmp(arg[iarg],"spin/atom/random") == 0)) { + if (iarg+3 > narg) utils::missing_cmd_args(FLERR, "set spin/atom/random", error); ivalue = utils::inumeric(FLERR,arg[iarg+1],false,lmp); dvalue = utils::numeric(FLERR,arg[iarg+2],false,lmp); + if ((strcmp(arg[iarg],"spin/random") == 0) && (comm->me == 0)) + error->warning(FLERR, "Set attribute spin/random is deprecated. " + "Please use spin/atom/random instead."); if (!atom->sp_flag) - error->all(FLERR,"Cannot set this attribute for this atom style"); + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); if (ivalue <= 0) - error->all(FLERR,"Invalid random number seed in set command"); + error->all(FLERR,"Invalid random number seed {} in set {} command", ivalue, arg[iarg]); if (dvalue <= 0.0) - error->all(FLERR,"Invalid dipole length in set command"); + error->all(FLERR,"Invalid spin magnitude {} in set {} command", dvalue, arg[iarg]); setrandom(SPIN_RANDOM); iarg += 3; + } else if (strcmp(arg[iarg],"radius/electron") == 0) { + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set radius/electron", error); + if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); + else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); + if (!atom->eradius_flag) + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); + set(RADIUS_ELECTRON); + iarg += 2; + + } else if (strcmp(arg[iarg],"spin/electron") == 0) { + if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "set spin/electron", error); + if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); + else dvalue = utils::numeric(FLERR,arg[iarg+1],false,lmp); + if (!atom->spin_flag) + error->all(FLERR,"Cannot set attribute {} for atom style {}", arg[iarg], atom->get_style()); + set(SPIN_ELECTRON); + iarg += 2; + } else if (strcmp(arg[iarg],"quat") == 0) { if (iarg+5 > narg) utils::missing_cmd_args(FLERR, "set quat", error); if (utils::strmatch(arg[iarg+1],"^v_")) varparse(arg[iarg+1],1); @@ -714,7 +742,7 @@ void Set::selection(int n) } else if (style == GROUP_SELECT) { int igroup = group->find(id); - if (igroup == -1) error->all(FLERR,"Could not find set group ID"); + if (igroup == -1) error->all(FLERR,"Could not find set group ID {}", id); int groupbit = group->bitmask[igroup]; int *mask = atom->mask; @@ -947,7 +975,7 @@ void Set::set(int keyword) // set magnetic moments - else if (keyword == SPIN) { + else if (keyword == SPIN_ATOM) { double **sp = atom->sp; double inorm = 1.0/sqrt(xvalue*xvalue+yvalue*yvalue+zvalue*zvalue); sp[i][0] = inorm*xvalue; diff --git a/unittest/commands/test_set_property.cpp b/unittest/commands/test_set_property.cpp index 0bd58cb53b..b75f0b465d 100644 --- a/unittest/commands/test_set_property.cpp +++ b/unittest/commands/test_set_property.cpp @@ -87,6 +87,11 @@ TEST_F(SetTest, NoBoxNoAtoms) TEST_FAILURE(".*ERROR: Unknown set command style: xxx.*", command("set xxx 1 x 0.0");); TEST_FAILURE(".*ERROR: Set keyword or custom property yyy does not exist.*", command("set type 1 yyy 0.0");); + + TEST_FAILURE(".*ERROR: Cannot set attribute spin/atom for atom style atomic.*", + command("set atom * spin/atom 1.0 1.0 0.0 0.0");); + TEST_FAILURE(".*ERROR: Cannot set attribute spin/atom/random for atom style atomic.*", + command("set atom * spin/atom/random 436273456 1.0");); } TEST_F(SetTest, StylesTypes) @@ -161,6 +166,126 @@ TEST_F(SetTest, StylesTypes) for (int i = 0; i < 8; ++i) sum += (atom->type[i] == 2) ? 1 : 0; ASSERT_EQ(sum, 4); + + TEST_FAILURE(".*ERROR: Numeric index 9 is out of bounds .1-8.*", command("set type 9 x 0.0");); + TEST_FAILURE(".*ERROR: Invalid range string: 3:10.*", command("set type 3:10 x 0.0");); + TEST_FAILURE(".*ERROR: Could not find set group ID nope.*", command("set group nope x 0.0");); +} + +TEST_F(SetTest, PosVelCharge) +{ + atomic_system("charge"); + ASSERT_EQ(atom->natoms, 8); + + BEGIN_HIDE_OUTPUT(); + command("set group top charge 1.0"); + command("set atom 5*8 charge -1.0"); + END_HIDE_OUTPUT(); + EXPECT_EQ(atom->q[0], 1); + EXPECT_EQ(atom->q[1], 1); + EXPECT_EQ(atom->q[2], 0); + EXPECT_EQ(atom->q[3], 0); + EXPECT_EQ(atom->q[4], -1); + EXPECT_EQ(atom->q[5], -1); + EXPECT_EQ(atom->q[6], -1); + EXPECT_EQ(atom->q[7], -1); + + BEGIN_HIDE_OUTPUT(); + command("variable xpos atom 0.5-x"); + command("variable ypos atom y*0.5"); + command("set atom * x v_xpos y v_ypos z 0.5"); + command("set group all vx v_xpos vy v_ypos vz 0.5"); + END_HIDE_OUTPUT(); + EXPECT_EQ(atom->x[0][0], 0.375); + EXPECT_EQ(atom->x[0][1], 0.0625); + EXPECT_EQ(atom->x[0][2], 0.5); + EXPECT_EQ(atom->x[1][0], -0.625); + EXPECT_EQ(atom->x[1][1], 0.0625); + EXPECT_EQ(atom->x[1][2], 0.5); + EXPECT_EQ(atom->x[2][0], 0.375); + EXPECT_EQ(atom->x[2][1], 0.5625); + EXPECT_EQ(atom->x[2][2], 0.5); + EXPECT_EQ(atom->x[3][0], -0.625); + EXPECT_EQ(atom->x[3][1], 0.5625); + EXPECT_EQ(atom->x[3][2], 0.5); + EXPECT_EQ(atom->x[4][0], 0.375); + EXPECT_EQ(atom->x[4][1], 0.0625); + EXPECT_EQ(atom->x[4][2], 0.5); + EXPECT_EQ(atom->x[5][0], -0.625); + EXPECT_EQ(atom->x[5][1], 0.0625); + EXPECT_EQ(atom->x[5][2], 0.5); + EXPECT_EQ(atom->x[6][0], 0.375); + EXPECT_EQ(atom->x[6][1], 0.5625); + EXPECT_EQ(atom->x[6][2], 0.5); + EXPECT_EQ(atom->x[7][0], -0.625); + EXPECT_EQ(atom->x[7][1], 0.5625); + EXPECT_EQ(atom->x[7][2], 0.5); + + EXPECT_EQ(atom->v[0][0], 0.125); + EXPECT_EQ(atom->v[0][1], 0.03125); + EXPECT_EQ(atom->v[0][2], 0.5); + EXPECT_EQ(atom->v[1][0], 1.125); + EXPECT_EQ(atom->v[1][1], 0.03125); + EXPECT_EQ(atom->v[1][2], 0.5); + EXPECT_EQ(atom->v[2][0], 0.125); + EXPECT_EQ(atom->v[2][1], 0.28125); + EXPECT_EQ(atom->v[2][2], 0.5); + EXPECT_EQ(atom->v[3][0], 1.125); + EXPECT_EQ(atom->v[3][1], 0.28125); + EXPECT_EQ(atom->v[3][2], 0.5); + EXPECT_EQ(atom->v[4][0], 0.125); + EXPECT_EQ(atom->v[4][1], 0.03125); + EXPECT_EQ(atom->v[4][2], 0.5); + EXPECT_EQ(atom->v[5][0], 1.125); + EXPECT_EQ(atom->v[5][1], 0.03125); + EXPECT_EQ(atom->v[5][2], 0.5); + EXPECT_EQ(atom->v[6][0], 0.125); + EXPECT_EQ(atom->v[6][1], 0.28125); + EXPECT_EQ(atom->v[6][2], 0.5); + EXPECT_EQ(atom->v[7][0], 1.125); + EXPECT_EQ(atom->v[7][1], 0.28125); + EXPECT_EQ(atom->v[7][2], 0.5); +} + +TEST_F(SetTest, SpinPackage) +{ + if (!Info::has_package("SPIN")) GTEST_SKIP(); + atomic_system("spin"); + ASSERT_EQ(atom->natoms, 8); + + BEGIN_HIDE_OUTPUT(); + command("set atom 1*2 spin/atom 0.5 0.1 0.5 -0.1"); + command("set atom 8 spin/atom/random 23974 0.25"); + END_HIDE_OUTPUT(); + constexpr double vx = 0.1; + constexpr double vy = 0.5; + constexpr double vz = -0.1; + constexpr double norm = 1.0 / sqrt(vx * vx + vy * vy + vz * vz); + EXPECT_EQ(atom->sp[0][0], vx * norm); + EXPECT_EQ(atom->sp[0][1], vy * norm); + EXPECT_EQ(atom->sp[0][2], vz * norm); + EXPECT_EQ(atom->sp[0][3], 0.5); + EXPECT_EQ(atom->sp[1][0], vx * norm); + EXPECT_EQ(atom->sp[1][1], vy * norm); + EXPECT_EQ(atom->sp[1][2], vz * norm); + EXPECT_EQ(atom->sp[1][3], 0.5); + EXPECT_NE(atom->sp[7][0], 0.0); + EXPECT_NE(atom->sp[7][1], 0.0); + EXPECT_NE(atom->sp[7][2], 0.0); + EXPECT_EQ(atom->sp[7][3], 0.25); + + for (int i = 2; i < 7; ++i) + for (int j = 0; j < 4; ++j) + EXPECT_EQ(atom->sp[i][j], 0); + + TEST_FAILURE(".*ERROR: Invalid spin magnitude -0.1 in set spin/atom command.*", + command("set atom * spin/atom -0.1 1.0 0.0 0.0");); + TEST_FAILURE(".*ERROR: At least one spin vector component must be non-zero.*", + command("set atom * spin/atom 1.0 0.0 0.0 0.0");); + TEST_FAILURE(".*ERROR: Invalid spin magnitude -0.2 in set spin/atom/random command.*", + command("set atom * spin/atom/random 436273456 -0.2");); + TEST_FAILURE(".*ERROR: Invalid random number seed 0 in set spin/atom/random command.*", + command("set atom * spin/atom/random 0 1.0");); } } // namespace LAMMPS_NS From f6b2846b8f87a9e9412835e7dad2a4a99134c752 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 29 Aug 2022 22:42:20 -0400 Subject: [PATCH 10/16] update error messages for compute property/atom --- src/compute_property_atom.cpp | 160 ++++++++++++++++------------------ 1 file changed, 75 insertions(+), 85 deletions(-) diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp index 606da288de..091ff3cd19 100644 --- a/src/compute_property_atom.cpp +++ b/src/compute_property_atom.cpp @@ -39,7 +39,7 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg), index(nullptr), colindex(nullptr), pack_choice(nullptr) { - if (narg < 4) error->all(FLERR,"Illegal compute property/atom command"); + if (narg < 4) utils::missing_cmd_args(FLERR, "compute property/atom", error); peratom_flag = 1; nvalues = narg - 3; @@ -52,6 +52,10 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : pack_choice = new FnPtrPack[nvalues]; index = new int[nvalues]; colindex = new int[nvalues]; + avec_ellipsoid = dynamic_cast(atom->style_match("ellipsoid")); + avec_body = dynamic_cast(atom->style_match("body")); + avec_line = dynamic_cast(atom->style_match("line")); + avec_tri = dynamic_cast(atom->style_match("tri")); int i; for (int iarg = 3; iarg < narg; iarg++) { @@ -61,8 +65,7 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : pack_choice[i] = &ComputePropertyAtom::pack_id; } else if (strcmp(arg[iarg],"mol") == 0) { if (!atom->molecule_flag) - error->all(FLERR,"Compute property/atom for " - "atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_molecule; } else if (strcmp(arg[iarg],"proc") == 0) { pack_choice[i] = &ComputePropertyAtom::pack_proc; @@ -123,217 +126,204 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : } else if (strcmp(arg[iarg],"q") == 0) { if (!atom->q_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_q; } else if (strcmp(arg[iarg],"mux") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_mux; } else if (strcmp(arg[iarg],"muy") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_muy; } else if (strcmp(arg[iarg],"muz") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_muz; } else if (strcmp(arg[iarg],"mu") == 0) { if (!atom->mu_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_mu; // pack magnetic variables } else if (strcmp(arg[iarg],"spx") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_spx; } else if (strcmp(arg[iarg],"spy") == 0) { + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_spy; } else if (strcmp(arg[iarg],"spz") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_spz; } else if (strcmp(arg[iarg],"sp") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_sp; } else if (strcmp(arg[iarg],"fmx") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_fmx; } else if (strcmp(arg[iarg],"fmy") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_fmy; } else if (strcmp(arg[iarg],"fmz") == 0) { if (!atom->sp_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_fmz; // bond count } else if (strcmp(arg[iarg],"nbonds") == 0) { if (!atom->molecule_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_nbonds; // finite-size particles } else if (strcmp(arg[iarg],"radius") == 0) { if (!atom->radius_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_radius; } else if (strcmp(arg[iarg],"diameter") == 0) { if (!atom->radius_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_diameter; } else if (strcmp(arg[iarg],"omegax") == 0) { if (!atom->omega_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_omegax; } else if (strcmp(arg[iarg],"omegay") == 0) { if (!atom->omega_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_omegay; } else if (strcmp(arg[iarg],"omegaz") == 0) { if (!atom->omega_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_omegaz; } else if (strcmp(arg[iarg],"angmomx") == 0) { if (!atom->angmom_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_angmomx; } else if (strcmp(arg[iarg],"angmomy") == 0) { if (!atom->angmom_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_angmomy; } else if (strcmp(arg[iarg],"angmomz") == 0) { if (!atom->angmom_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_angmomz; } else if (strcmp(arg[iarg],"shapex") == 0) { - avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); - if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_ellipsoid) + error->all(FLERR,"Compute property/atom {} requires atom style ellipsoid", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_shapex; } else if (strcmp(arg[iarg],"shapey") == 0) { - avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); - if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_ellipsoid) + error->all(FLERR,"Compute property/atom {} requires atom style ellipsoid", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_shapey; } else if (strcmp(arg[iarg],"shapez") == 0) { - avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); - if (!avec_ellipsoid) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_ellipsoid) + error->all(FLERR,"Compute property/atom {} requires atom style ellipsoid", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_shapez; } else if (strcmp(arg[iarg],"quatw") == 0) { - avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); - avec_body = dynamic_cast( atom->style_match("body")); if (!avec_ellipsoid && !avec_body && !atom->quat_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_quatw; } else if (strcmp(arg[iarg],"quati") == 0) { - avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); - avec_body = dynamic_cast( atom->style_match("body")); if (!avec_ellipsoid && !avec_body && !atom->quat_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_quati; } else if (strcmp(arg[iarg],"quatj") == 0) { - avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); - avec_body = dynamic_cast( atom->style_match("body")); if (!avec_ellipsoid && !avec_body && !atom->quat_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_quatj; } else if (strcmp(arg[iarg],"quatk") == 0) { - avec_ellipsoid = dynamic_cast( atom->style_match("ellipsoid")); - avec_body = dynamic_cast( atom->style_match("body")); if (!avec_ellipsoid && !avec_body && !atom->quat_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_quatk; } else if (strcmp(arg[iarg],"tqx") == 0) { if (!atom->torque_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_tqx; } else if (strcmp(arg[iarg],"tqy") == 0) { if (!atom->torque_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_tqy; } else if (strcmp(arg[iarg],"tqz") == 0) { if (!atom->torque_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + error->all(FLERR,"Compute property/atom {} is not available", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_tqz; } else if (strcmp(arg[iarg],"end1x") == 0) { - avec_line = dynamic_cast( atom->style_match("line")); - if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_line) + error->all(FLERR,"Compute property/atom {} requires atom style line", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_end1x; } else if (strcmp(arg[iarg],"end1y") == 0) { - avec_line = dynamic_cast( atom->style_match("line")); - if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_line) + error->all(FLERR,"Compute property/atom {} requires atom style line", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_end1y; } else if (strcmp(arg[iarg],"end1z") == 0) { - avec_line = dynamic_cast( atom->style_match("line")); - if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_line) + error->all(FLERR,"Compute property/atom {} requires atom style line", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_end1z; } else if (strcmp(arg[iarg],"end2x") == 0) { - avec_line = dynamic_cast( atom->style_match("line")); - if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_line) + error->all(FLERR,"Compute property/atom {} requires atom style line", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_end2x; } else if (strcmp(arg[iarg],"end2y") == 0) { - avec_line = dynamic_cast( atom->style_match("line")); - if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_line) + error->all(FLERR,"Compute property/atom {} requires atom style line", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_end2y; } else if (strcmp(arg[iarg],"end2z") == 0) { - avec_line = dynamic_cast( atom->style_match("line")); - if (!avec_line) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_line) + error->all(FLERR,"Compute property/atom {} requires atom style line", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_end2z; } else if (strcmp(arg[iarg],"corner1x") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner1x; } else if (strcmp(arg[iarg],"corner1y") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner1y; } else if (strcmp(arg[iarg],"corner1z") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner1z; } else if (strcmp(arg[iarg],"corner2x") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner2x; - } else if (strcmp(arg[iarg],"corner2y") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner2y; } else if (strcmp(arg[iarg],"corner2z") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner2z; } else if (strcmp(arg[iarg],"corner3x") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner3x; } else if (strcmp(arg[iarg],"corner3y") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner3y; } else if (strcmp(arg[iarg],"corner3z") == 0) { - avec_tri = dynamic_cast( atom->style_match("tri")); - if (!avec_tri) error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); + if (!avec_tri) + error->all(FLERR,"Compute property/atom {} requires atom style tri", arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_corner3z; - } else if (strcmp(arg[iarg],"nbonds") == 0) { - if (!atom->molecule_flag) - error->all(FLERR,"Compute property/atom for atom property that isn't allocated"); - pack_choice[i] = &ComputePropertyAtom::pack_nbonds; - // custom per-atom vector or array } else if (utils::strmatch(arg[iarg],"^[id]2?_")) { @@ -386,7 +376,7 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : } else { index[i] = atom->avec->property_atom(arg[iarg]); if (index[i] < 0) - error->all(FLERR,"Invalid keyword in compute property/atom command"); + error->all(FLERR,"Invalid keyword {} in compute property/atom command",arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_atom_style; } } @@ -398,9 +388,9 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : ComputePropertyAtom::~ComputePropertyAtom() { - delete [] pack_choice; - delete [] index; - delete [] colindex; + delete[] pack_choice; + delete[] index; + delete[] colindex; memory->destroy(vector_atom); memory->destroy(array_atom); } From 58fcf26581054a78b05db7e5c300e9fe71aaa43f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 29 Aug 2022 23:32:41 -0400 Subject: [PATCH 11/16] add first tests for compute property/atom --- unittest/commands/test_set_property.cpp | 193 +++++++++++++++--------- 1 file changed, 124 insertions(+), 69 deletions(-) diff --git a/unittest/commands/test_set_property.cpp b/unittest/commands/test_set_property.cpp index b75f0b465d..87dbaedddd 100644 --- a/unittest/commands/test_set_property.cpp +++ b/unittest/commands/test_set_property.cpp @@ -17,6 +17,7 @@ #include "compute.h" #include "domain.h" #include "math_const.h" +#include "modify.h" #include "../testing/core.h" #include "gmock/gmock.h" @@ -82,7 +83,12 @@ TEST_F(SetTest, NoBoxNoAtoms) BEGIN_HIDE_OUTPUT(); command("create_atoms 1 single 0.5 0.5 0.5"); + command("compute 0 all property/atom proc"); END_HIDE_OUTPUT(); + auto compute = lmp->modify->get_compute_by_id("0"); + compute->compute_peratom(); + ASSERT_EQ(compute->vector_atom[0], 0); + TEST_FAILURE(".*ERROR: Illegal set command: need at least four.*", command("set type 1 x");); TEST_FAILURE(".*ERROR: Unknown set command style: xxx.*", command("set xxx 1 x 0.0");); TEST_FAILURE(".*ERROR: Set keyword or custom property yyy does not exist.*", @@ -92,6 +98,11 @@ TEST_F(SetTest, NoBoxNoAtoms) command("set atom * spin/atom 1.0 1.0 0.0 0.0");); TEST_FAILURE(".*ERROR: Cannot set attribute spin/atom/random for atom style atomic.*", command("set atom * spin/atom/random 436273456 1.0");); + + TEST_FAILURE(".*ERROR: Illegal compute property/atom command: missing argument.*", + command("compute 1 all property/atom");); + TEST_FAILURE(".*ERROR: Compute property/atom mol is not available.*", + command("compute 1 all property/atom mol");); } TEST_F(SetTest, StylesTypes) @@ -104,7 +115,12 @@ TEST_F(SetTest, StylesTypes) command("set group top type 2"); command("set region back type 3"); command("set region left mol 2"); + command("compute 1 all property/atom id type mol"); END_HIDE_OUTPUT(); + auto compute = lmp->modify->get_compute_by_id("1"); + compute->compute_peratom(); + + ASSERT_NE(compute, nullptr); ASSERT_EQ(atom->type[0], 2); ASSERT_EQ(atom->type[1], 2); ASSERT_EQ(atom->type[2], 1); @@ -114,6 +130,45 @@ TEST_F(SetTest, StylesTypes) ASSERT_EQ(atom->type[6], 1); ASSERT_EQ(atom->type[7], 1); + ASSERT_EQ(atom->molecule[0], 2); + ASSERT_EQ(atom->molecule[1], 1); + ASSERT_EQ(atom->molecule[2], 2); + ASSERT_EQ(atom->molecule[3], 1); + ASSERT_EQ(atom->molecule[4], 2); + ASSERT_EQ(atom->molecule[5], 1); + ASSERT_EQ(atom->molecule[6], 2); + ASSERT_EQ(atom->molecule[7], 1); + + // atom ID + ASSERT_EQ(compute->array_atom[0][0], 1); + ASSERT_EQ(compute->array_atom[1][0], 2); + ASSERT_EQ(compute->array_atom[2][0], 3); + ASSERT_EQ(compute->array_atom[3][0], 4); + ASSERT_EQ(compute->array_atom[4][0], 5); + ASSERT_EQ(compute->array_atom[5][0], 6); + ASSERT_EQ(compute->array_atom[6][0], 7); + ASSERT_EQ(compute->array_atom[7][0], 8); + + // atom type + ASSERT_EQ(compute->array_atom[0][1], 2); + ASSERT_EQ(compute->array_atom[1][1], 2); + ASSERT_EQ(compute->array_atom[2][1], 1); + ASSERT_EQ(compute->array_atom[3][1], 1); + ASSERT_EQ(compute->array_atom[4][1], 2); + ASSERT_EQ(compute->array_atom[5][1], 2); + ASSERT_EQ(compute->array_atom[6][1], 1); + ASSERT_EQ(compute->array_atom[7][1], 1); + + // mol ID + ASSERT_EQ(compute->array_atom[0][2], 2); + ASSERT_EQ(compute->array_atom[1][2], 1); + ASSERT_EQ(compute->array_atom[2][2], 2); + ASSERT_EQ(compute->array_atom[3][2], 1); + ASSERT_EQ(compute->array_atom[4][2], 2); + ASSERT_EQ(compute->array_atom[5][2], 1); + ASSERT_EQ(compute->array_atom[6][2], 2); + ASSERT_EQ(compute->array_atom[7][2], 1); + BEGIN_HIDE_OUTPUT(); command("set mol 1 type 4"); command("set atom 4*7 type 5"); @@ -181,14 +236,14 @@ TEST_F(SetTest, PosVelCharge) command("set group top charge 1.0"); command("set atom 5*8 charge -1.0"); END_HIDE_OUTPUT(); - EXPECT_EQ(atom->q[0], 1); - EXPECT_EQ(atom->q[1], 1); - EXPECT_EQ(atom->q[2], 0); - EXPECT_EQ(atom->q[3], 0); - EXPECT_EQ(atom->q[4], -1); - EXPECT_EQ(atom->q[5], -1); - EXPECT_EQ(atom->q[6], -1); - EXPECT_EQ(atom->q[7], -1); + ASSERT_EQ(atom->q[0], 1); + ASSERT_EQ(atom->q[1], 1); + ASSERT_EQ(atom->q[2], 0); + ASSERT_EQ(atom->q[3], 0); + ASSERT_EQ(atom->q[4], -1); + ASSERT_EQ(atom->q[5], -1); + ASSERT_EQ(atom->q[6], -1); + ASSERT_EQ(atom->q[7], -1); BEGIN_HIDE_OUTPUT(); command("variable xpos atom 0.5-x"); @@ -196,55 +251,55 @@ TEST_F(SetTest, PosVelCharge) command("set atom * x v_xpos y v_ypos z 0.5"); command("set group all vx v_xpos vy v_ypos vz 0.5"); END_HIDE_OUTPUT(); - EXPECT_EQ(atom->x[0][0], 0.375); - EXPECT_EQ(atom->x[0][1], 0.0625); - EXPECT_EQ(atom->x[0][2], 0.5); - EXPECT_EQ(atom->x[1][0], -0.625); - EXPECT_EQ(atom->x[1][1], 0.0625); - EXPECT_EQ(atom->x[1][2], 0.5); - EXPECT_EQ(atom->x[2][0], 0.375); - EXPECT_EQ(atom->x[2][1], 0.5625); - EXPECT_EQ(atom->x[2][2], 0.5); - EXPECT_EQ(atom->x[3][0], -0.625); - EXPECT_EQ(atom->x[3][1], 0.5625); - EXPECT_EQ(atom->x[3][2], 0.5); - EXPECT_EQ(atom->x[4][0], 0.375); - EXPECT_EQ(atom->x[4][1], 0.0625); - EXPECT_EQ(atom->x[4][2], 0.5); - EXPECT_EQ(atom->x[5][0], -0.625); - EXPECT_EQ(atom->x[5][1], 0.0625); - EXPECT_EQ(atom->x[5][2], 0.5); - EXPECT_EQ(atom->x[6][0], 0.375); - EXPECT_EQ(atom->x[6][1], 0.5625); - EXPECT_EQ(atom->x[6][2], 0.5); - EXPECT_EQ(atom->x[7][0], -0.625); - EXPECT_EQ(atom->x[7][1], 0.5625); - EXPECT_EQ(atom->x[7][2], 0.5); + ASSERT_EQ(atom->x[0][0], 0.375); + ASSERT_EQ(atom->x[0][1], 0.0625); + ASSERT_EQ(atom->x[0][2], 0.5); + ASSERT_EQ(atom->x[1][0], -0.625); + ASSERT_EQ(atom->x[1][1], 0.0625); + ASSERT_EQ(atom->x[1][2], 0.5); + ASSERT_EQ(atom->x[2][0], 0.375); + ASSERT_EQ(atom->x[2][1], 0.5625); + ASSERT_EQ(atom->x[2][2], 0.5); + ASSERT_EQ(atom->x[3][0], -0.625); + ASSERT_EQ(atom->x[3][1], 0.5625); + ASSERT_EQ(atom->x[3][2], 0.5); + ASSERT_EQ(atom->x[4][0], 0.375); + ASSERT_EQ(atom->x[4][1], 0.0625); + ASSERT_EQ(atom->x[4][2], 0.5); + ASSERT_EQ(atom->x[5][0], -0.625); + ASSERT_EQ(atom->x[5][1], 0.0625); + ASSERT_EQ(atom->x[5][2], 0.5); + ASSERT_EQ(atom->x[6][0], 0.375); + ASSERT_EQ(atom->x[6][1], 0.5625); + ASSERT_EQ(atom->x[6][2], 0.5); + ASSERT_EQ(atom->x[7][0], -0.625); + ASSERT_EQ(atom->x[7][1], 0.5625); + ASSERT_EQ(atom->x[7][2], 0.5); - EXPECT_EQ(atom->v[0][0], 0.125); - EXPECT_EQ(atom->v[0][1], 0.03125); - EXPECT_EQ(atom->v[0][2], 0.5); - EXPECT_EQ(atom->v[1][0], 1.125); - EXPECT_EQ(atom->v[1][1], 0.03125); - EXPECT_EQ(atom->v[1][2], 0.5); - EXPECT_EQ(atom->v[2][0], 0.125); - EXPECT_EQ(atom->v[2][1], 0.28125); - EXPECT_EQ(atom->v[2][2], 0.5); - EXPECT_EQ(atom->v[3][0], 1.125); - EXPECT_EQ(atom->v[3][1], 0.28125); - EXPECT_EQ(atom->v[3][2], 0.5); - EXPECT_EQ(atom->v[4][0], 0.125); - EXPECT_EQ(atom->v[4][1], 0.03125); - EXPECT_EQ(atom->v[4][2], 0.5); - EXPECT_EQ(atom->v[5][0], 1.125); - EXPECT_EQ(atom->v[5][1], 0.03125); - EXPECT_EQ(atom->v[5][2], 0.5); - EXPECT_EQ(atom->v[6][0], 0.125); - EXPECT_EQ(atom->v[6][1], 0.28125); - EXPECT_EQ(atom->v[6][2], 0.5); - EXPECT_EQ(atom->v[7][0], 1.125); - EXPECT_EQ(atom->v[7][1], 0.28125); - EXPECT_EQ(atom->v[7][2], 0.5); + ASSERT_EQ(atom->v[0][0], 0.125); + ASSERT_EQ(atom->v[0][1], 0.03125); + ASSERT_EQ(atom->v[0][2], 0.5); + ASSERT_EQ(atom->v[1][0], 1.125); + ASSERT_EQ(atom->v[1][1], 0.03125); + ASSERT_EQ(atom->v[1][2], 0.5); + ASSERT_EQ(atom->v[2][0], 0.125); + ASSERT_EQ(atom->v[2][1], 0.28125); + ASSERT_EQ(atom->v[2][2], 0.5); + ASSERT_EQ(atom->v[3][0], 1.125); + ASSERT_EQ(atom->v[3][1], 0.28125); + ASSERT_EQ(atom->v[3][2], 0.5); + ASSERT_EQ(atom->v[4][0], 0.125); + ASSERT_EQ(atom->v[4][1], 0.03125); + ASSERT_EQ(atom->v[4][2], 0.5); + ASSERT_EQ(atom->v[5][0], 1.125); + ASSERT_EQ(atom->v[5][1], 0.03125); + ASSERT_EQ(atom->v[5][2], 0.5); + ASSERT_EQ(atom->v[6][0], 0.125); + ASSERT_EQ(atom->v[6][1], 0.28125); + ASSERT_EQ(atom->v[6][2], 0.5); + ASSERT_EQ(atom->v[7][0], 1.125); + ASSERT_EQ(atom->v[7][1], 0.28125); + ASSERT_EQ(atom->v[7][2], 0.5); } TEST_F(SetTest, SpinPackage) @@ -261,22 +316,22 @@ TEST_F(SetTest, SpinPackage) constexpr double vy = 0.5; constexpr double vz = -0.1; constexpr double norm = 1.0 / sqrt(vx * vx + vy * vy + vz * vz); - EXPECT_EQ(atom->sp[0][0], vx * norm); - EXPECT_EQ(atom->sp[0][1], vy * norm); - EXPECT_EQ(atom->sp[0][2], vz * norm); - EXPECT_EQ(atom->sp[0][3], 0.5); - EXPECT_EQ(atom->sp[1][0], vx * norm); - EXPECT_EQ(atom->sp[1][1], vy * norm); - EXPECT_EQ(atom->sp[1][2], vz * norm); - EXPECT_EQ(atom->sp[1][3], 0.5); - EXPECT_NE(atom->sp[7][0], 0.0); - EXPECT_NE(atom->sp[7][1], 0.0); - EXPECT_NE(atom->sp[7][2], 0.0); - EXPECT_EQ(atom->sp[7][3], 0.25); + ASSERT_EQ(atom->sp[0][0], vx * norm); + ASSERT_EQ(atom->sp[0][1], vy * norm); + ASSERT_EQ(atom->sp[0][2], vz * norm); + ASSERT_EQ(atom->sp[0][3], 0.5); + ASSERT_EQ(atom->sp[1][0], vx * norm); + ASSERT_EQ(atom->sp[1][1], vy * norm); + ASSERT_EQ(atom->sp[1][2], vz * norm); + ASSERT_EQ(atom->sp[1][3], 0.5); + ASSERT_NE(atom->sp[7][0], 0.0); + ASSERT_NE(atom->sp[7][1], 0.0); + ASSERT_NE(atom->sp[7][2], 0.0); + ASSERT_EQ(atom->sp[7][3], 0.25); for (int i = 2; i < 7; ++i) for (int j = 0; j < 4; ++j) - EXPECT_EQ(atom->sp[i][j], 0); + ASSERT_EQ(atom->sp[i][j], 0); TEST_FAILURE(".*ERROR: Invalid spin magnitude -0.1 in set spin/atom command.*", command("set atom * spin/atom -0.1 1.0 0.0 0.0");); From bfb15c6cc6e2407b6990688ef01866d5636fdd24 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 30 Aug 2022 06:11:17 -0400 Subject: [PATCH 12/16] support setting electron spin and radius with the set command --- doc/src/set.rst | 21 ++++++++++++++++++--- src/set.cpp | 19 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/doc/src/set.rst b/doc/src/set.rst index c6c44ceb45..3d970d7044 100644 --- a/doc/src/set.rst +++ b/doc/src/set.rst @@ -16,9 +16,10 @@ Syntax * keyword = *type* or *type/fraction* or *type/ratio* or *type/subset* or *mol* or *x* or *y* or *z* or *vx* or *vy* or *vz* or *charge* or *dipole* or *dipole/random* or *quat* or *spin/atom* or *spin/atom/random* or - *quat* or *quat/random* or *diameter* or *shape* or - *length* or *tri* or *theta* or *theta/random* or *angmom* or - *omega* or *mass* or *density* or *density/disc* or + *spin/electron* or *radius/electron* or + *quat* or *quat/random* or *diameter* or *shape* or *length* or *tri* or + *theta* or *theta/random* or *angmom* or *omega* or + *mass* or *density* or *density/disc* or *volume* or *image* or *bond* or *angle* or *dihedral* or *improper* or *sph/e* or *sph/cv* or *sph/rho* or *smd/contact/radius* or *smd/mass/density* or *dpd/theta* or @@ -62,6 +63,10 @@ Syntax *spin/atom/random* value = seed Dlen seed = random # seed (positive integer) for magnetic spin orientations Dlen = magnitude of magnetic spin vector (in Bohr magneton's unit) + *radius/electron* values = eradius + eradius = electron radius (or fixed-core radius) (distance units) + *spin/electron* value = espin + espin = electron spin (+1/-1), 0 = nuclei, 2 = fixed-core, 3 = pseudo-cores (i.e. ECP) *quat* values = a b c theta a,b,c = unit vector to rotate particle around via right-hand rule theta = rotation angle (degrees) @@ -290,6 +295,16 @@ Keyword *spin/atom/random* randomizes the orientation of the magnetic spin vectors for the selected atoms and sets the magnitude of each to the specified *Dlen* value. This keyword was previously called *spin/random*. +.. versionadded:: TBD + +Keyword *radius/electron* uses the specified value to set the radius of +electrons or fixed cores. + +.. versionadded:: TBD + +Keyword *spin/electron* sets the spin of an electron (+/- 1) or indicates +nuclei (=0), fixed-cores (=2), or pseudo-cores (= 3). + Keyword *quat* uses the specified values to create a quaternion (4-vector) that represents the orientation of the selected atoms. The particles must define a quaternion for their orientation diff --git a/src/set.cpp b/src/set.cpp index 601bdd9e56..80c524f8a4 100644 --- a/src/set.cpp +++ b/src/set.cpp @@ -976,6 +976,8 @@ void Set::set(int keyword) // set magnetic moments else if (keyword == SPIN_ATOM) { + if (dvalue < 0.0) + error->one(FLERR,"Incorrect value for atomic spin magnitude: {}", dvalue); double **sp = atom->sp; double inorm = 1.0/sqrt(xvalue*xvalue+yvalue*yvalue+zvalue*zvalue); sp[i][0] = inorm*xvalue; @@ -984,6 +986,23 @@ void Set::set(int keyword) sp[i][3] = dvalue; } + // set electron radius + + else if (keyword == RADIUS_ELECTRON) { + atom->eradius[i] = dvalue; + if (dvalue < 0.0) + error->one(FLERR,"Incorrect value for electron radius: {}", dvalue); + } + + // set electron spin + + else if (keyword == SPIN_ELECTRON) { + if ((dvalue == -1) || (dvalue == 1) || (dvalue == 0) || (dvalue == 2) || (dvalue == 3)) + atom->spin[i] = (int)dvalue; + else + error->one(FLERR,"Incorrect value for electron spin: {}", dvalue); + } + // set quaternion orientation of ellipsoid or tri or body particle or sphere/bpm // enforce quat rotation vector in z dir for 2d systems From 2c0eb10d62a4266fac2ee485392ae09841de8d5e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 30 Aug 2022 06:12:28 -0400 Subject: [PATCH 13/16] label electron spin with "espin" instead of "spin" but be backward compatible --- doc/src/compute_property_atom.rst | 8 ++++++-- doc/src/read_data.rst | 8 ++++---- doc/utils/sphinx-config/false_positives.txt | 1 + src/AWPMD/atom_vec_wavepacket.cpp | 19 ++++++++++--------- src/EFF/atom_vec_electron.cpp | 19 ++++++++++--------- src/atom.cpp | 8 +++++--- 6 files changed, 36 insertions(+), 27 deletions(-) diff --git a/doc/src/compute_property_atom.rst b/doc/src/compute_property_atom.rst index 34ff62944a..2e9619062e 100644 --- a/doc/src/compute_property_atom.rst +++ b/doc/src/compute_property_atom.rst @@ -31,7 +31,7 @@ Syntax corner2x, corner2y, corner2z, corner3x, corner3y, corner3z, i_name, d_name, i2_name[I], d2_name[I], - vfrac, s0, spin, eradius, ervel, erforce, + vfrac, s0, espin, eradius, ervel, erforce, rho, drho, e, de, cv, buckling, .. parsed-literal:: @@ -76,7 +76,7 @@ Syntax .. parsed-literal:: EFF and AWPMD package per-atom properties: - spin = electron spin + espin = electron spin eradius = electron radius ervel = electron radial velocity erforce = electron radial force @@ -167,6 +167,10 @@ triangular particles and define the corner points of each triangle. In addition, the various per-atom quantities listed above for specific packages are only accessible by this command. +.. versionchanged:: TBD + + The *espin* property was previously called *spin*. + Output info """"""""""" diff --git a/doc/src/read_data.rst b/doc/src/read_data.rst index 853d86785e..bcde47e970 100644 --- a/doc/src/read_data.rst +++ b/doc/src/read_data.rst @@ -631,7 +631,7 @@ of analysis. * - edpd - atom-ID atom-type edpd_temp edpd_cv x y z * - electron - - atom-ID atom-type q spin eradius x y z + - atom-ID atom-type q espin eradius x y z * - ellipsoid - atom-ID atom-type ellipsoidflag density x y z * - full @@ -663,7 +663,7 @@ of analysis. * - tri - atom-ID molecule-ID atom-type triangleflag density x y z * - wavepacket - - atom-ID atom-type charge spin eradius etag cs_re cs_im x y z + - atom-ID atom-type charge espin eradius etag cs_re cs_im x y z * - hybrid - atom-ID atom-type x y z sub-style1 sub-style2 ... @@ -680,11 +680,12 @@ The per-atom values have these meanings and units, listed alphabetically: * cv = heat capacity (need units) for SPH particles * density = density of particle (mass/distance\^3 or mass/distance\^2 or mass/distance units, depending on dimensionality of particle) * diameter = diameter of spherical atom (distance units) -* esph = energy (need units) for SPH particles * edpd_temp = temperature for eDPD particles (temperature units) * edpd_cv = volumetric heat capacity for eDPD particles (energy/temperature/volume units) * ellipsoidflag = 1 for ellipsoidal particles, 0 for point particles * eradius = electron radius (or fixed-core radius) +* esph = energy (need units) for SPH particles +* espin = electron spin (+1/-1), 0 = nuclei, 2 = fixed-core, 3 = pseudo-cores (i.e. ECP) * etag = integer ID of electron that each wave packet belongs to * kradius = kernel radius for SMD particles (distance units) * lineflag = 1 for line segment particles, 0 for point or spherical particles @@ -695,7 +696,6 @@ The per-atom values have these meanings and units, listed alphabetically: * mux,muy,muz = components of dipole moment of atom (dipole units) * q = charge on atom (charge units) * rho = density (need units) for SPH particles -* spin = electron spin (+1/-1), 0 = nuclei, 2 = fixed-core, 3 = pseudo-cores (i.e. ECP) * sp = magnitude of magnetic spin of atom (Bohr magnetons) * spx,spy,spz = components of magnetic spin of atom (unit vector) * template-atom = which atom within a template molecule the atom is diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 8b3689c367..106fdf44ea 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -974,6 +974,7 @@ Eshelby eskm Espanol esph +espin estretch esu esub diff --git a/src/AWPMD/atom_vec_wavepacket.cpp b/src/AWPMD/atom_vec_wavepacket.cpp index 59a503571e..b4950e2ef0 100644 --- a/src/AWPMD/atom_vec_wavepacket.cpp +++ b/src/AWPMD/atom_vec_wavepacket.cpp @@ -39,18 +39,18 @@ AtomVecWavepacket::AtomVecWavepacket(LAMMPS *lmp) : AtomVec(lmp) // order of fields in a string does not matter // except: fields_data_atom & fields_data_vel must match data file - fields_grow = {"q", "spin", "eradius", "ervel", "erforce", + fields_grow = {"q", "espin", "eradius", "ervel", "erforce", "cs", "csforce", "vforce", "ervelforce", "etag"}; - fields_copy = {"q", "spin", "eradius", "ervel", "cs", "etag"}; + fields_copy = {"q", "espin", "eradius", "ervel", "cs", "etag"}; fields_comm = {"eradius"}; fields_comm_vel = {"eradius", "ervel", "cs"}; fields_reverse = {"erforce", "ervelforce", "vforce", "csforce"}; - fields_border = {"q", "spin", "eradius", "etag"}; - fields_border_vel = {"q", "spin", "eradius", "etag", "ervel", "cs"}; - fields_exchange = {"q", "spin", "eradius", "ervel", "etag", "cs"}; - fields_restart = {"q", "spin", "eradius", "ervel", "etag", "cs"}; - fields_create = {"q", "spin", "eradius", "ervel", "etag", "cs"}; - fields_data_atom = {"id", "type", "q", "spin", "eradius", "etag", "cs", "x"}; + fields_border = {"q", "espin", "eradius", "etag"}; + fields_border_vel = {"q", "espin", "eradius", "etag", "ervel", "cs"}; + fields_exchange = {"q", "espin", "eradius", "ervel", "etag", "cs"}; + fields_restart = {"q", "espin", "eradius", "ervel", "etag", "cs"}; + fields_create = {"q", "espin", "eradius", "ervel", "etag", "cs"}; + fields_data_atom = {"id", "type", "q", "espin", "eradius", "etag", "cs", "x"}; fields_data_vel = {"id", "v", "ervel"}; setup_fields(); @@ -107,7 +107,8 @@ void AtomVecWavepacket::data_atom_post(int ilocal) int AtomVecWavepacket::property_atom(const std::string &name) { - if (name == "spin") return 0; + if (name == "espin") return 0; + if (name == "spin") return 0; // backward compatibility if (name == "eradius") return 1; if (name == "ervel") return 2; if (name == "erforce") return 3; diff --git a/src/EFF/atom_vec_electron.cpp b/src/EFF/atom_vec_electron.cpp index 5d600b5037..e456c1916c 100644 --- a/src/EFF/atom_vec_electron.cpp +++ b/src/EFF/atom_vec_electron.cpp @@ -53,17 +53,17 @@ AtomVecElectron::AtomVecElectron(LAMMPS *lmp) : AtomVec(lmp) // order of fields in a string does not matter // except: fields_data_atom & fields_data_vel must match data file - fields_grow = {"q", "spin", "eradius", "ervel", "erforce"}; - fields_copy = {"q", "spin", "eradius", "ervel"}; + fields_grow = {"q", "espin", "eradius", "ervel", "erforce"}; + fields_copy = {"q", "espin", "eradius", "ervel"}; fields_comm = {"eradius"}; fields_comm_vel = {"eradius"}; fields_reverse = {"erforce"}; - fields_border = {"q", "spin", "eradius"}; - fields_border_vel = {"q", "spin", "eradius"}; - fields_exchange = {"q", "spin", "eradius", "ervel"}; - fields_restart = {"q", "spin", "eradius", "ervel"}; - fields_create = {"q", "spin", "eradius", "ervel"}; - fields_data_atom = {"id", "type", "q", "spin", "eradius", "x"}; + fields_border = {"q", "espin", "eradius"}; + fields_border_vel = {"q", "espin", "eradius"}; + fields_exchange = {"q", "espin", "eradius", "ervel"}; + fields_restart = {"q", "espin", "eradius", "ervel"}; + fields_create = {"q", "espin", "eradius", "ervel"}; + fields_data_atom = {"id", "type", "q", "espin", "eradius", "x"}; fields_data_vel = {"id", "v", "ervel"}; setup_fields(); @@ -119,7 +119,8 @@ void AtomVecElectron::data_atom_post(int ilocal) int AtomVecElectron::property_atom(const std::string &name) { - if (name == "spin") return 0; + if (name == "espin") return 0; + if (name == "spin") return 0; // backward compatibility if (name == "eradius") return 1; if (name == "ervel") return 2; if (name == "erforce") return 3; diff --git a/src/atom.cpp b/src/atom.cpp index 66552c5508..500dc4ff1d 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -480,7 +480,7 @@ void Atom::peratom_create() // EFF package - add_peratom("spin",&spin,INT,0); + add_peratom("espin",&spin,INT,0); add_peratom("eradius",&eradius,DOUBLE,0); add_peratom("ervel",&ervel,DOUBLE,0); add_peratom("erforce",&erforce,DOUBLE,0,1); // set per-thread flag @@ -2706,7 +2706,8 @@ void *Atom::extract(const char *name) // EFF and AWPMD packages - if (strcmp(name,"spin") == 0) return (void *) spin; + if (strcmp(name,"espin") == 0) return (void *) spin; + if (strcmp(name,"spin") == 0) return (void *) spin; // backward compatibility if (strcmp(name,"eradius") == 0) return (void *) eradius; if (strcmp(name,"ervel") == 0) return (void *) ervel; if (strcmp(name,"erforce") == 0) return (void *) erforce; @@ -2830,7 +2831,8 @@ int Atom::extract_datatype(const char *name) if (strcmp(name,"s0") == 0) return LAMMPS_DOUBLE; if (strcmp(name,"x0") == 0) return LAMMPS_DOUBLE_2D; - if (strcmp(name,"spin") == 0) return LAMMPS_INT; + if (strcmp(name,"espin") == 0) return LAMMPS_INT; + if (strcmp(name,"spin") == 0) return LAMMPS_INT; // backwards compatibility if (strcmp(name,"eradius") == 0) return LAMMPS_DOUBLE; if (strcmp(name,"ervel") == 0) return LAMMPS_DOUBLE; if (strcmp(name,"erforce") == 0) return LAMMPS_DOUBLE; From 238e6371b2d632c03059cb6d11686af748284234 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 30 Aug 2022 06:12:45 -0400 Subject: [PATCH 14/16] improve error message --- src/compute_property_atom.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp index 091ff3cd19..4d55549d99 100644 --- a/src/compute_property_atom.cpp +++ b/src/compute_property_atom.cpp @@ -376,7 +376,8 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) : } else { index[i] = atom->avec->property_atom(arg[iarg]); if (index[i] < 0) - error->all(FLERR,"Invalid keyword {} in compute property/atom command",arg[iarg]); + error->all(FLERR,"Invalid keyword {} for atom style {} in compute property/atom command ", + atom->get_style(), arg[iarg]); pack_choice[i] = &ComputePropertyAtom::pack_atom_style; } } From 70a157f3714cefb3809ca5e0a87fab466f2098d4 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 30 Aug 2022 11:41:52 -0400 Subject: [PATCH 15/16] add test for EFF package properties --- unittest/commands/test_set_property.cpp | 65 ++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/unittest/commands/test_set_property.cpp b/unittest/commands/test_set_property.cpp index 87dbaedddd..3675a1b18f 100644 --- a/unittest/commands/test_set_property.cpp +++ b/unittest/commands/test_set_property.cpp @@ -117,10 +117,11 @@ TEST_F(SetTest, StylesTypes) command("set region left mol 2"); command("compute 1 all property/atom id type mol"); END_HIDE_OUTPUT(); + auto compute = lmp->modify->get_compute_by_id("1"); + ASSERT_NE(compute, nullptr); compute->compute_peratom(); - ASSERT_NE(compute, nullptr); ASSERT_EQ(atom->type[0], 2); ASSERT_EQ(atom->type[1], 2); ASSERT_EQ(atom->type[2], 1); @@ -342,6 +343,68 @@ TEST_F(SetTest, SpinPackage) TEST_FAILURE(".*ERROR: Invalid random number seed 0 in set spin/atom/random command.*", command("set atom * spin/atom/random 0 1.0");); } + +TEST_F(SetTest, EffPackage) +{ + if (!Info::has_package("EFF")) GTEST_SKIP(); + atomic_system("electron"); + ASSERT_EQ(atom->natoms, 8); + + BEGIN_HIDE_OUTPUT(); + command("set atom 1*2 spin/electron -1"); + command("set atom 3*4 spin/electron 1"); + command("set atom 5 spin/electron 0"); + command("set atom 6 spin/electron 2"); + command("set atom 7* spin/electron 3"); + command("set region left radius/electron 0.5"); + command("set region right radius/electron 1.0"); + command("compute 1 all property/atom espin eradius"); + END_HIDE_OUTPUT(); + + auto compute = lmp->modify->get_compute_by_id("1"); + ASSERT_NE(compute, nullptr); + compute->compute_peratom(); + + EXPECT_EQ(atom->spin[0],-1); + EXPECT_EQ(atom->spin[1],-1); + EXPECT_EQ(atom->spin[2],1); + EXPECT_EQ(atom->spin[3],1); + EXPECT_EQ(atom->spin[4],0); + EXPECT_EQ(atom->spin[5],2); + EXPECT_EQ(atom->spin[6],3); + EXPECT_EQ(atom->spin[7],3); + EXPECT_EQ(atom->eradius[0],0.5); + EXPECT_EQ(atom->eradius[1],1.0); + EXPECT_EQ(atom->eradius[2],0.5); + EXPECT_EQ(atom->eradius[3],1.0); + EXPECT_EQ(atom->eradius[4],0.5); + EXPECT_EQ(atom->eradius[5],1.0); + EXPECT_EQ(atom->eradius[6],0.5); + EXPECT_EQ(atom->eradius[7],1.0); + + EXPECT_EQ(compute->array_atom[0][0],-1); + EXPECT_EQ(compute->array_atom[1][0],-1); + EXPECT_EQ(compute->array_atom[2][0],1); + EXPECT_EQ(compute->array_atom[3][0],1); + EXPECT_EQ(compute->array_atom[4][0],0); + EXPECT_EQ(compute->array_atom[5][0],2); + EXPECT_EQ(compute->array_atom[6][0],3); + EXPECT_EQ(compute->array_atom[7][0],3); + EXPECT_EQ(compute->array_atom[0][1],0.5); + EXPECT_EQ(compute->array_atom[1][1],1.0); + EXPECT_EQ(compute->array_atom[2][1],0.5); + EXPECT_EQ(compute->array_atom[3][1],1.0); + EXPECT_EQ(compute->array_atom[4][1],0.5); + EXPECT_EQ(compute->array_atom[5][1],1.0); + EXPECT_EQ(compute->array_atom[6][1],0.5); + EXPECT_EQ(compute->array_atom[7][1],1.0); + + TEST_FAILURE(".*ERROR on proc 0: Incorrect value for electron spin: 0.5.*", + command("set atom * spin/electron 0.5");); + TEST_FAILURE(".*ERROR on proc 0: Incorrect value for electron radius: -0.5.*", + command("set atom * radius/electron 0.5");); +} + } // namespace LAMMPS_NS int main(int argc, char **argv) From b0b62fe1acd5ec91c5e24742fdd0a20103796a36 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 30 Aug 2022 12:32:22 -0400 Subject: [PATCH 16/16] fix death test --- unittest/commands/test_set_property.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/unittest/commands/test_set_property.cpp b/unittest/commands/test_set_property.cpp index 3675a1b18f..f482463060 100644 --- a/unittest/commands/test_set_property.cpp +++ b/unittest/commands/test_set_property.cpp @@ -358,10 +358,10 @@ TEST_F(SetTest, EffPackage) command("set atom 7* spin/electron 3"); command("set region left radius/electron 0.5"); command("set region right radius/electron 1.0"); - command("compute 1 all property/atom espin eradius"); + command("compute 2 all property/atom espin eradius"); END_HIDE_OUTPUT(); - auto compute = lmp->modify->get_compute_by_id("1"); + auto compute = lmp->modify->get_compute_by_id("2"); ASSERT_NE(compute, nullptr); compute->compute_peratom(); @@ -402,7 +402,7 @@ TEST_F(SetTest, EffPackage) TEST_FAILURE(".*ERROR on proc 0: Incorrect value for electron spin: 0.5.*", command("set atom * spin/electron 0.5");); TEST_FAILURE(".*ERROR on proc 0: Incorrect value for electron radius: -0.5.*", - command("set atom * radius/electron 0.5");); + command("set atom * radius/electron -0.5");); } } // namespace LAMMPS_NS