diff --git a/src/atom.cpp b/src/atom.cpp index 0e7cbfb0fd..a60d08bf39 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -1940,41 +1940,22 @@ void Atom::set_mass(const char *file, int line, int /*narg*/, char **arg) if (mass == nullptr) error->all(file,line, "Cannot set per-type atom mass for atom style {}", atom_style); - // clang-format on - std::string typestr = utils::utf8_subst(utils::trim(arg[0])); - switch (utils::is_type(typestr)) { + char *typestr = utils::expand_type(file, line, arg[0], Atom::ATOM, lmp); + if (typestr) arg[0] = typestr; - case 0: { // numeric - int lo, hi; - utils::bounds(file, line, typestr, 1, ntypes, lo, hi, error); - if ((lo < 1) || (hi > ntypes)) - error->all(file, line, "Invalid atom type {} for atom mass", typestr); + int lo, hi; + utils::bounds(file, line, arg[0], 1, ntypes, lo, hi, error); + if ((lo < 1) || (hi > ntypes)) + error->all(file, line, "Invalid atom type {} for atom mass", arg[0]); - const double value = utils::numeric(FLERR, arg[1], false, lmp); - if (value <= 0.0) - error->all(file, line, "Invalid atom mass value {} for type {}", value, typestr); + const double value = utils::numeric(FLERR, arg[1], false, lmp); + if (value <= 0.0) + error->all(file, line, "Invalid atom mass value {} for type {}", value, arg[0]); - for (int itype = lo; itype <= hi; itype++) { - mass[itype] = value; - mass_setflag[itype] = 1; - } - break; - } - - case 1: { // type label - if (!atom->labelmapflag) error->all(FLERR, "Invalid atom type {} for setting mass", typestr); - int itype = lmap->find(typestr, Atom::ATOM); - if (itype == -1) error->all(file, line, "Invalid type {} for setting mass", typestr); - mass[itype] = utils::numeric(FLERR, arg[1], false, lmp); - mass_setflag[itype] = 1; - break; - } - - default: // invalid - error->one(FLERR, "Invalid mass setting"); - break; + for (int itype = lo; itype <= hi; itype++) { + mass[itype] = value; + mass_setflag[itype] = 1; } - // clang-format off } /* ---------------------------------------------------------------------- diff --git a/src/input.cpp b/src/input.cpp index 72465cd9a9..a641f300a3 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -710,41 +710,6 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag) strcpy(str,str2); } -/* ---------------------------------------------------------------------- - substitute type labels with numeric value - reallocate str to hold expanded version if necessary - return flag if new pointer, caller will need to delete [] - if type is a valid numerical string (can include '*'), do not modify -------------------------------------------------------------------------- */ - -int Input::readtype(char *&str, int mode) -{ - int numflag = 1; - int n = strlen(str); - for (int i = 0; i < n; i++) - if (!isdigit(str[i]) && str[i] != '*') numflag = 0; - if (numflag) return 0; - if (!atom->labelmapflag) error->all(FLERR,fmt::format("Invalid type {}",str)); - - int type,max,max2; - char typechar[256]; - std::string labelstr = utils::trim(str); - - type = atom->lmap->find(labelstr,mode); - if (type == -1) error->all(FLERR,fmt::format("Invalid type {}",str)); - sprintf(typechar,"%d",type); - - max = n + 1; - max2 = strlen(typechar) + 1; - if (max2 > max) { - str = new char[max2]; - strcpy(str,typechar); - return 1; - } else strcpy(str,typechar); - - return 0; -} - /* ---------------------------------------------------------------------- return number of triple quotes in line ------------------------------------------------------------------------- */ @@ -1363,9 +1328,10 @@ void Input::angle_coeff() error->all(FLERR,"Angle_coeff command before angle_style is defined"); if (atom->avec->angles_allow == 0) error->all(FLERR,"Angle_coeff command when no angles allowed"); - int newflag = readtype(arg[0],Atom::ANGLE); + char *newarg = utils::expand_type(FLERR, arg[0], Atom::ANGLE, lmp); + if (newarg) arg[0] = newarg; force->angle->coeff(narg,arg); - if (newflag) delete[] arg[0]; + delete[] newarg; } /* ---------------------------------------------------------------------- */ @@ -1406,9 +1372,10 @@ void Input::bond_coeff() error->all(FLERR,"Bond_coeff command before bond_style is defined"); if (atom->avec->bonds_allow == 0) error->all(FLERR,"Bond_coeff command when no bonds allowed"); - int newflag = readtype(arg[0],Atom::BOND); + char *newarg = utils::expand_type(FLERR, arg[0], Atom::BOND, lmp); + if (newarg) arg[0] = newarg; force->bond->coeff(narg,arg); - if (newflag) delete[] arg[0]; + delete[] newarg; } /* ---------------------------------------------------------------------- */ @@ -1511,9 +1478,10 @@ void Input::dihedral_coeff() error->all(FLERR,"Dihedral_coeff command before dihedral_style is defined"); if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Dihedral_coeff command when no dihedrals allowed"); - int newflag = readtype(arg[0],Atom::DIHEDRAL); + char *newarg = utils::expand_type(FLERR, arg[0], Atom::DIHEDRAL, lmp); + if (newarg) arg[0] = newarg; force->dihedral->coeff(narg,arg); - if (newflag) delete[] arg[0]; + delete[] newarg; } /* ---------------------------------------------------------------------- */ @@ -1590,9 +1558,10 @@ void Input::improper_coeff() error->all(FLERR,"Improper_coeff command before improper_style is defined"); if (atom->avec->impropers_allow == 0) error->all(FLERR,"Improper_coeff command when no impropers allowed"); - int newflag = readtype(arg[0],Atom::IMPROPER); + char *newarg = utils::expand_type(FLERR, arg[0], Atom::IMPROPER, lmp); + if (newarg) arg[0] = newarg; force->improper->coeff(narg,arg); - if (newflag) delete[] arg[0]; + delete[] newarg; } /* ---------------------------------------------------------------------- */ @@ -1729,14 +1698,12 @@ void Input::package() } else if (strcmp(arg[0],"kokkos") == 0) { if (lmp->kokkos == nullptr || lmp->kokkos->kokkos_exists == 0) - error->all(FLERR, - "Package kokkos command without KOKKOS package enabled"); + error->all(FLERR, "Package kokkos command without KOKKOS package enabled"); lmp->kokkos->accelerator(narg-1,&arg[1]); } else if (strcmp(arg[0],"omp") == 0) { if (!modify->check_package("OMP")) - error->all(FLERR, - "Package omp command without OPENMP package installed"); + error->all(FLERR, "Package omp command without OPENMP package installed"); std::string fixcmd = "package_omp all OMP"; for (int i = 1; i < narg; i++) fixcmd += std::string(" ") + arg[i]; @@ -1744,14 +1711,13 @@ void Input::package() } else if (strcmp(arg[0],"intel") == 0) { if (!modify->check_package("INTEL")) - error->all(FLERR, - "Package intel command without INTEL package installed"); + error->all(FLERR, "Package intel command without INTEL package installed"); std::string fixcmd = "package_intel all INTEL"; for (int i = 1; i < narg; i++) fixcmd += std::string(" ") + arg[i]; modify->add_fix(fixcmd); - } else error->all(FLERR,"Illegal package command"); + } else error->all(FLERR,"Unknown package keyword: {}", arg[0]); } /* ---------------------------------------------------------------------- */ @@ -1766,29 +1732,27 @@ void Input::pair_coeff() || (strcmp(arg[1],"*") != 0)))) error->all(FLERR,"Incorrect args for pair coefficients"); - int newflag0 = readtype(arg[0],Atom::ATOM); - int newflag1 = readtype(arg[1],Atom::ATOM); + char *newarg0 = utils::expand_type(FLERR, arg[0], Atom::ATOM, lmp); + if (newarg0) arg[0] = newarg0; + char *newarg1 = utils::expand_type(FLERR, arg[1], Atom::ATOM, lmp); + if (newarg1) arg[1] = newarg1; // if arg[1] < arg[0], and neither contain a wildcard, reorder - int tmpflag,itype,jtype; - char *str; + int itype,jtype; if (strchr(arg[0],'*') == nullptr && strchr(arg[1],'*') == nullptr) { itype = utils::numeric(FLERR,arg[0],false,lmp); jtype = utils::numeric(FLERR,arg[1],false,lmp); if (jtype < itype) { - str = arg[0]; + char *str = arg[0]; arg[0] = arg[1]; arg[1] = str; - tmpflag = newflag0; - newflag0 = newflag1; - newflag1 = tmpflag; } } force->pair->coeff(narg,arg); - if (newflag0) delete[] arg[0]; - if (newflag1) delete[] arg[1]; + delete[] newarg0; + delete[] newarg1; } /* ---------------------------------------------------------------------- */ diff --git a/src/input.h b/src/input.h index 1af903e1fa..5bd531ca0a 100644 --- a/src/input.h +++ b/src/input.h @@ -34,13 +34,11 @@ class Input : protected Pointers { Input(class LAMMPS *, int, char **); ~Input() override; - void file(); // process all input - void file(const char *); // process an input script - char *one(const std::string &); // process a single command - void substitute(char *&, char *&, int &, int &, int); - // substitute for variables in a string - void write_echo(const std::string &); // send text to active echo file pointers - int readtype(char *&, int); // substitute type label with numeric type + void file(); // process all input + void file(const char *); // process an input script + char *one(const std::string &); // process a single command + void substitute(char *&, char *&, int &, int &, int); // substitute for variables in a string + void write_echo(const std::string &); // send text to active echo file pointers protected: char *command; // ptr to current command diff --git a/src/utils.cpp b/src/utils.cpp index 00f2095c35..cd4c0892d1 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -767,6 +767,8 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod return newarg; } +static const char *labeltypes[] = {"Atom", "Bond", "Angle", "Dihedral", "Improper"}; + /* ------------------------------------------------------------------------- Expand type string to numeric string from labelmap. Return copy of expanded type or null pointer. @@ -775,12 +777,16 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod char *utils::expand_type(const char *file, int line, const std::string &str, int mode, LAMMPS *lmp) { if (!lmp) return nullptr; - if (is_type(str) == 1) { + const std::string typestr = utils::utf8_subst(str); + if (is_type(typestr) == 1) { if (!lmp->atom->labelmapflag) - lmp->error->all(file, line, "Type string {} cannot be used without a labelmap", str); + lmp->error->all(file, line, "{} type string {} cannot be used without a labelmap", + labeltypes[mode], typestr); - int type = lmp->atom->lmap->find(str, mode); - if (type == -1) lmp->error->all(file, line, "Type string {} not found in labelmap", str); + int type = lmp->atom->lmap->find(typestr, mode); + if (type == -1) + lmp->error->all(file, line, "{} type string {} not found in labelmap", labeltypes[mode], + typestr); return utils::strdup(std::to_string(type)); } else diff --git a/unittest/commands/test_labelmap.cpp b/unittest/commands/test_labelmap.cpp index 1e6bf4305b..1f2b599550 100644 --- a/unittest/commands/test_labelmap.cpp +++ b/unittest/commands/test_labelmap.cpp @@ -66,7 +66,7 @@ TEST_F(LabelMapTest, Atoms) END_HIDE_OUTPUT(); EXPECT_EQ(domain->box_exist, 1); EXPECT_EQ(atom->lmap, nullptr); - TEST_FAILURE(".*ERROR: Type string C1 cannot be used without a labelmap.*", + TEST_FAILURE(".*ERROR: Atom type string C1 cannot be used without a labelmap.*", utils::expand_type(FLERR, "C1", Atom::ATOM, lmp);); BEGIN_HIDE_OUTPUT(); @@ -109,7 +109,7 @@ TEST_F(LabelMapTest, Atoms) expanded = utils::expand_type(FLERR, "O#", Atom::ATOM, lmp); EXPECT_THAT(expanded, StrEq("3")); delete[] expanded; - TEST_FAILURE(".*ERROR: Type string XX not found in labelmap.*", + TEST_FAILURE(".*ERROR: Atom type string XX not found in labelmap.*", utils::expand_type(FLERR, "XX", Atom::ATOM, lmp);); TEST_FAILURE(".*ERROR: Labelmap atom type 0 must be within 1-4.*", @@ -277,8 +277,14 @@ TEST_F(LabelMapTest, Topology) expanded = utils::expand_type(FLERR, "C1-N2-C1-N2", Atom::IMPROPER, lmp); EXPECT_THAT(expanded, StrEq("1")); delete[] expanded; - TEST_FAILURE(".*ERROR: Type string XX not found in labelmap.*", + TEST_FAILURE(".*ERROR: Bond type string XX not found in labelmap.*", utils::expand_type(FLERR, "XX", Atom::BOND, lmp);); + TEST_FAILURE(".*ERROR: Angle type string XX not found in labelmap.*", + utils::expand_type(FLERR, "XX", Atom::ANGLE, lmp);); + TEST_FAILURE(".*ERROR: Dihedral type string XX not found in labelmap.*", + utils::expand_type(FLERR, "XX", Atom::DIHEDRAL, lmp);); + TEST_FAILURE(".*ERROR: Improper type string XX not found in labelmap.*", + utils::expand_type(FLERR, "XX", Atom::IMPROPER, lmp);); } } // namespace LAMMPS_NS