replace Input::readtype() with utils::expand_type()

This commit is contained in:
Axel Kohlmeyer
2022-09-05 06:16:18 -04:00
parent 75e897b2fe
commit 4f3f2412fb
5 changed files with 60 additions and 105 deletions

View File

@ -1940,41 +1940,22 @@ void Atom::set_mass(const char *file, int line, int /*narg*/, char **arg)
if (mass == nullptr) if (mass == nullptr)
error->all(file,line, "Cannot set per-type atom mass for atom style {}", atom_style); error->all(file,line, "Cannot set per-type atom mass for atom style {}", atom_style);
// clang-format on char *typestr = utils::expand_type(file, line, arg[0], Atom::ATOM, lmp);
std::string typestr = utils::utf8_subst(utils::trim(arg[0])); if (typestr) arg[0] = typestr;
switch (utils::is_type(typestr)) {
case 0: { // numeric int lo, hi;
int lo, hi; utils::bounds(file, line, arg[0], 1, ntypes, lo, hi, error);
utils::bounds(file, line, typestr, 1, ntypes, lo, hi, error); if ((lo < 1) || (hi > ntypes))
if ((lo < 1) || (hi > ntypes)) error->all(file, line, "Invalid atom type {} for atom mass", arg[0]);
error->all(file, line, "Invalid atom type {} for atom mass", typestr);
const double value = utils::numeric(FLERR, arg[1], false, lmp); const double value = utils::numeric(FLERR, arg[1], false, lmp);
if (value <= 0.0) if (value <= 0.0)
error->all(file, line, "Invalid atom mass value {} for type {}", value, typestr); error->all(file, line, "Invalid atom mass value {} for type {}", value, arg[0]);
for (int itype = lo; itype <= hi; itype++) { for (int itype = lo; itype <= hi; itype++) {
mass[itype] = value; mass[itype] = value;
mass_setflag[itype] = 1; 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;
} }
// clang-format off
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -710,41 +710,6 @@ void Input::substitute(char *&str, char *&str2, int &max, int &max2, int flag)
strcpy(str,str2); 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 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"); error->all(FLERR,"Angle_coeff command before angle_style is defined");
if (atom->avec->angles_allow == 0) if (atom->avec->angles_allow == 0)
error->all(FLERR,"Angle_coeff command when no angles allowed"); 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); 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"); error->all(FLERR,"Bond_coeff command before bond_style is defined");
if (atom->avec->bonds_allow == 0) if (atom->avec->bonds_allow == 0)
error->all(FLERR,"Bond_coeff command when no bonds allowed"); 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); 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"); error->all(FLERR,"Dihedral_coeff command before dihedral_style is defined");
if (atom->avec->dihedrals_allow == 0) if (atom->avec->dihedrals_allow == 0)
error->all(FLERR,"Dihedral_coeff command when no dihedrals allowed"); 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); 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"); error->all(FLERR,"Improper_coeff command before improper_style is defined");
if (atom->avec->impropers_allow == 0) if (atom->avec->impropers_allow == 0)
error->all(FLERR,"Improper_coeff command when no impropers allowed"); 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); 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) { } else if (strcmp(arg[0],"kokkos") == 0) {
if (lmp->kokkos == nullptr || lmp->kokkos->kokkos_exists == 0) if (lmp->kokkos == nullptr || lmp->kokkos->kokkos_exists == 0)
error->all(FLERR, error->all(FLERR, "Package kokkos command without KOKKOS package enabled");
"Package kokkos command without KOKKOS package enabled");
lmp->kokkos->accelerator(narg-1,&arg[1]); lmp->kokkos->accelerator(narg-1,&arg[1]);
} else if (strcmp(arg[0],"omp") == 0) { } else if (strcmp(arg[0],"omp") == 0) {
if (!modify->check_package("OMP")) if (!modify->check_package("OMP"))
error->all(FLERR, error->all(FLERR, "Package omp command without OPENMP package installed");
"Package omp command without OPENMP package installed");
std::string fixcmd = "package_omp all OMP"; std::string fixcmd = "package_omp all OMP";
for (int i = 1; i < narg; i++) fixcmd += std::string(" ") + arg[i]; 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) { } else if (strcmp(arg[0],"intel") == 0) {
if (!modify->check_package("INTEL")) if (!modify->check_package("INTEL"))
error->all(FLERR, error->all(FLERR, "Package intel command without INTEL package installed");
"Package intel command without INTEL package installed");
std::string fixcmd = "package_intel all INTEL"; std::string fixcmd = "package_intel all INTEL";
for (int i = 1; i < narg; i++) fixcmd += std::string(" ") + arg[i]; for (int i = 1; i < narg; i++) fixcmd += std::string(" ") + arg[i];
modify->add_fix(fixcmd); 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)))) || (strcmp(arg[1],"*") != 0))))
error->all(FLERR,"Incorrect args for pair coefficients"); error->all(FLERR,"Incorrect args for pair coefficients");
int newflag0 = readtype(arg[0],Atom::ATOM); char *newarg0 = utils::expand_type(FLERR, arg[0], Atom::ATOM, lmp);
int newflag1 = readtype(arg[1],Atom::ATOM); 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 // if arg[1] < arg[0], and neither contain a wildcard, reorder
int tmpflag,itype,jtype; int itype,jtype;
char *str;
if (strchr(arg[0],'*') == nullptr && strchr(arg[1],'*') == nullptr) { if (strchr(arg[0],'*') == nullptr && strchr(arg[1],'*') == nullptr) {
itype = utils::numeric(FLERR,arg[0],false,lmp); itype = utils::numeric(FLERR,arg[0],false,lmp);
jtype = utils::numeric(FLERR,arg[1],false,lmp); jtype = utils::numeric(FLERR,arg[1],false,lmp);
if (jtype < itype) { if (jtype < itype) {
str = arg[0]; char *str = arg[0];
arg[0] = arg[1]; arg[0] = arg[1];
arg[1] = str; arg[1] = str;
tmpflag = newflag0;
newflag0 = newflag1;
newflag1 = tmpflag;
} }
} }
force->pair->coeff(narg,arg); force->pair->coeff(narg,arg);
if (newflag0) delete[] arg[0]; delete[] newarg0;
if (newflag1) delete[] arg[1]; delete[] newarg1;
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */

View File

@ -34,13 +34,11 @@ class Input : protected Pointers {
Input(class LAMMPS *, int, char **); Input(class LAMMPS *, int, char **);
~Input() override; ~Input() override;
void file(); // process all input void file(); // process all input
void file(const char *); // process an input script void file(const char *); // process an input script
char *one(const std::string &); // process a single command char *one(const std::string &); // process a single command
void substitute(char *&, char *&, int &, int &, int); void substitute(char *&, char *&, int &, int &, int); // substitute for variables in a string
// substitute for variables in a string void write_echo(const std::string &); // send text to active echo file pointers
void write_echo(const std::string &); // send text to active echo file pointers
int readtype(char *&, int); // substitute type label with numeric type
protected: protected:
char *command; // ptr to current command char *command; // ptr to current command

View File

@ -767,6 +767,8 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod
return newarg; return newarg;
} }
static const char *labeltypes[] = {"Atom", "Bond", "Angle", "Dihedral", "Improper"};
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
Expand type string to numeric string from labelmap. Expand type string to numeric string from labelmap.
Return copy of expanded type or null pointer. 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) char *utils::expand_type(const char *file, int line, const std::string &str, int mode, LAMMPS *lmp)
{ {
if (!lmp) return nullptr; 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) 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); int type = lmp->atom->lmap->find(typestr, mode);
if (type == -1) lmp->error->all(file, line, "Type string {} not found in labelmap", str); if (type == -1)
lmp->error->all(file, line, "{} type string {} not found in labelmap", labeltypes[mode],
typestr);
return utils::strdup(std::to_string(type)); return utils::strdup(std::to_string(type));
} else } else

View File

@ -66,7 +66,7 @@ TEST_F(LabelMapTest, Atoms)
END_HIDE_OUTPUT(); END_HIDE_OUTPUT();
EXPECT_EQ(domain->box_exist, 1); EXPECT_EQ(domain->box_exist, 1);
EXPECT_EQ(atom->lmap, nullptr); 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);); utils::expand_type(FLERR, "C1", Atom::ATOM, lmp););
BEGIN_HIDE_OUTPUT(); BEGIN_HIDE_OUTPUT();
@ -109,7 +109,7 @@ TEST_F(LabelMapTest, Atoms)
expanded = utils::expand_type(FLERR, "O#", Atom::ATOM, lmp); expanded = utils::expand_type(FLERR, "O#", Atom::ATOM, lmp);
EXPECT_THAT(expanded, StrEq("3")); EXPECT_THAT(expanded, StrEq("3"));
delete[] expanded; 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);); utils::expand_type(FLERR, "XX", Atom::ATOM, lmp););
TEST_FAILURE(".*ERROR: Labelmap atom type 0 must be within 1-4.*", TEST_FAILURE(".*ERROR: Labelmap atom type 0 must be within 1-4.*",
@ -277,8 +277,14 @@ TEST_F(LabelMapTest, Topology)
expanded = utils::expand_type(FLERR, "C1-N2-C1-N2", Atom::IMPROPER, lmp); expanded = utils::expand_type(FLERR, "C1-N2-C1-N2", Atom::IMPROPER, lmp);
EXPECT_THAT(expanded, StrEq("1")); EXPECT_THAT(expanded, StrEq("1"));
delete[] expanded; 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);); 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 } // namespace LAMMPS_NS